Re: Copy constructor, return by value and const references
On 9 Nov., 09:26, SG wrote:
On 9 Nov., 02:16, Jan Lellmann wrote:
using namespace std
class A {
private:
friend A createA(); // private default constructor
A() { cout << "default constructor" << endl; };
A(const A& from) { // private copy constructor
cout << "copy constructor" << endl;
}
public:
int get() {
return 1;
}
};
A createA() {
return A();
}
int main(int, char**)
{
createA().get(); // this compiles
const A& ref(createA()); // "error: A::A(const A&) is privat=
e"
}
The standard allows the compiler to copy a temporary to another
temporary before binding it to a reference-to-const. Obviously you
need to have a public copy ctor for that. C++0x will get rid of this
rule and make your program well-formed. Some compilers don't even
complain about these things (g++) because they always *directly* bind
a temporary to a ref-to-const.
To be specific: 8.5.3 [dcl.init.ref] (Initializers, references). The
bullet point for class-type rvalues:
=97 If the initializer expression is an rvalue, with T2 a class
type, and =93cv1 T1=94 is reference-compatible with =93cv2 T2,=94 the
reference is bound in one of the following ways (the choice is
implementation-defined):
=97 The reference is bound to the object represented by the
rvalue (see 3.10) or to a subobject within that object.
=97 A temporary of type =93cv1 T2=94 [sic] is created, and a
constructor is called to copy the entire rvalue object into
the temporary. The reference is bound to the temporary or to
a subobject within the temporary.
The constructor that would be used to make the copy shall be
callable whether or not the copy is actually done.
In C++0x compilers are forced to go with the first option:
=97 If the initializer expression is an rvalue, with T2 a class
type, and =93cv1 T1=94 is reference-compatible with =93cv2 T2,=94 the
reference is bound to the object represented by the rvalue
(see 3.10) or to a sub-object within that object.
Cheers,
SG