class A
{
public:
A(const int n_);
A(const A& that_);
A& operator=(const A& that_);
};
A::A(const int n_)
{ cout << "A::A(int), n_=" << n_ << endl; }
A::A(const A& that_) // This is line 21
{ cout << "A::A(const A&)" << endl; }
A& A::operator=(const A& that_)
{ cout << "A::operator=(const A&)" << endl; }
int foo(const A& a_)
{ return 20; }
int main()
{
A a(foo(A(10))); // This is line 38
return 0;
}
Executing this code gives o/p:
A::A(int), n_=10
A::A(int), n_=20
Apparently the copy constructor is never called.
class A
{
public:
A(const int n_);
A& operator=(const A& that_);
private:
A(const A& that_);
};
However, if we make it private, this compile error occurs:
Test.cpp: In function ‘int main()’:
Test.cpp:21: error: ‘A::A(const A&)’ is private
Test.cpp:38: error: within this context
Why does the compiler complain when it doesn't actually use the copy constructor?
I am using gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)
Core defect 391 explains the issue.
Basically, the current C++ standard requires a copy constructor to be available when passing a temporary of class type to a const reference.
This requirement will be removed in C++0x.
The logic behind requiring a copy constructor comes from this case:
C f();
const C& r = f(); // a copy is generated for r to refer to
The 2003 standard, in §12.2/1, states:
Even when the creation of the temporary object is avoided (12.8), all the semantic restrictions must be respected as if the temporary object was created. [Example: even if the copy constructor is not called, all the semantic restrictions, such as accessibility (clause 11), shall be satisfied. ]
There are similar examples around. From what I gather, the compiler is free to generate temporaries or optimize them away.
As far I see you are not using the copy constructor anywhere. In the statement foo(A(10))
you are creating a temporary object of class A and passing it as a const-reference to foo. The foo returns an integer which is used in the construction of object a
. Hence I don't see where the copy constructor is getting involved here and how NRVO comes into picture. Also, I compiled the following code by making the copy constructor private and it compiled fine in VS2008.
using namespace std;
class A
{
public:
A(const int n_);
private:
A(const A& that_);
A& operator=(const A& that_);
};
A::A(const int n_)
{ cout << "A::A(int), n_=" << n_ << endl; }
A::A(const A& that_) // This is line 21
{ cout << "A::A(const A&)" << endl; }
A& A::operator=(const A& that_)
{
cout << "A::operator=(const A&)" << endl;
return *this;
}
int foo(const A& a_)
{ return 20; }
int main(int argc,char *argv[])
{
A a(foo(A(10))); // This is line 38
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With