explicit copy constructor ignored even if exact argument was provided

724 views Asked by At

The copy constructor has been provided. While using it exactly same type is passed to argument. Still the it seems the compiler( gcc/g++ 4.8.2) ignores existence of explicit copy constructor. The code generates compilation error. Why? The error is:

t.cpp: In function ‘A f(const A&)’:
t.cpp:19:12: error: no matching function for call to ‘A::A(const A&)’
     return a;  //compilation error with gcc 4.8.2
            ^
t.cpp:19:12: note: candidate is:
t.cpp:14:5: note: A::A()
     A(){}
     ^
t.cpp:14:5: note:   candidate expects 0 arguments, 1 provided
t.cpp:21:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

I have already gone through
Why I am not able to invoke 'explicit a (string x)'? and Explicit copy constructor. Based on the those links and i have tried the forcing copy construction (to avoid optimization,Refer to my commented code).

#include <iostream>
using namespace std;

class A 
{
public:
    explicit A(const A& a)   // an explicit copy constructor
    //A(const A&)   // an copy constructor, pretty much default one. 
                    //using it solves any compile problem.
    {
        cout << "\nin the copy constructor" << endl;
    }

    A(){}
};
//////////////////////////////////
A f(const A &a)
{   
    return a;  //compilation error with gcc 4.8.2
    //return A(a);   // even tried this to avoid optimization. does not work 
}
///////////////////////////////////
int main()
{
    //A a;
    //f(a);  
    return 0;
}
1

There are 1 answers

2
leewz On

The copy constructor is called implicitly on return (and also when passing an argument by value).

This code would call the copy constructor twice:

A f(const A &a)
{   
    return A(a);
}

The A(a) means an explicit copy, and then there is an implicit copy on return.

If you want to disallow implicit copying, then you can't return by copy, either. You'll have to return by reference or pointer (probably with a new'd copy).


In C++11 and up, I believe that the code above would instead call the move constructor (if defined) for the return (though it would still call the copy constructor for the explicit call), and that should be more efficient.