From: Anubhav on
class A {
};

class B : public A {
B(const B& other);
public:
explicit B(){}
};

int main() {
A const & a = B(); // L1
A a2 = B(); // L2
}

Why VC++ 2010 and g++ give error related to private copy constructor
in 'B' in Line L2. I understand the Line L1 is governed by $8.5.3/5 (C+
+ 2003)

Dabs.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 12 Aug., 09:03, Anubhav <rkld...(a)gmail.com> wrote:
> class A {
>
> };
>
> class B : public A {
> B(const B& other);
> public:
> explicit B(){}
>
> };
>
> int main() {
> A const & a = B(); // L1
> A a2 = B(); // L2
>
> }
>
> Why VC++ 2010 and g++ give error related to private copy constructor
> in 'B' in Line L2. I understand the Line L1 is governed by $8.5.3/5 (C+
> + 2003)

A diagnostic is required in C++03, because it is implementation-
defined whether the rvalue is directly bound or whether a copy of
that rvalue is directly bound. Note that the first bullet in 8.5.3/5 does
not really apply, because the first sub-bullet is not satisfied (the
initializer expression is no lvalue) nor is any implicit conversion
taking place here. Therefore we end in the second bullet of that
paragraph:

"Otherwise, the reference shall be to a non-volatile const type (i.e.,
cv1 shall be const)."

The spec proceeds:

"� If the initializer expression is an rvalue, with T2 a class type, and
�cv1 T1� is reference-compatible with �cv2 T2,� the reference is bound
in one of the following ways (the choice is implementation-defined):
� The reference is bound to the object represented by the rvalue
(see 3.10) or to a sub-object within that object.
� A temporary of type �cv1 T2� [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 sub-object within the
temporary.93)
The constructor that would be used to make the copy shall be callable
whether or not the copy is actually done."

As of C++0x, direct-binding to the initial object is required and this
program is well-formed given the new spec.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Francis Glassborow on
Anubhav wrote:
> class A {
> };
>
> class B : public A {
> B(const B& other);
> public:
> explicit B(){}
> };
>
> int main() {
> A const & a = B(); // L1

There is no problem here B() just creates a temporary B object and binds
it to a reference to A. Of course as the classes are not polymorphic the
result is a complete waste of time because the only behaviour you can
get for a2 is the behaviour of an A.

> A a2 = B(); // L2

Quite different. First a B object is constructed, then it is copied and
finally sliced (of course in the absence of any data members slicing is
trivial) to fit the A destination. However it is the copy that is sliced
and though the copy process can (and almost always will be) elided the
compiler must first check that the copying can be done. In this case it
cannot.

> }
>
> Why VC++ 2010 and g++ give error related to private copy constructor
> in 'B' in Line L2. I understand the Line L1 is governed by $8.5.3/5 (C+
> + 2003)
>

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bo Persson on
Anubhav wrote:
> class A {
> };
>
> class B : public A {
> B(const B& other);
> public:
> explicit B(){}
> };
>
> int main() {
> A const & a = B(); // L1
> A a2 = B(); // L2
> }
>
> Why VC++ 2010 and g++ give error related to private copy constructor
> in 'B' in Line L2. I understand the Line L1 is governed by $8.5.3/5
> (C+ + 2003)
>
> Dabs.

The compiler is allowed to copy the temporary created by B(). To be
consistent for all compilers, the language rules says that there must
be an accessible copy constructor, whether the object is copied or
not.

I believe this rule will be removed in C++0x. Seems like no compilers
will actually copy anything here.


Bo Persson


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Anubhav on
> The compiler is allowed to copy the temporary created by B(). To be
> consistent for all compilers, the language rules says that there must
> be an accessible copy constructor, whether the object is copied or
> not.
>
> I believe this rule will be removed in C++0x. Seems like no compilers
> will actually copy anything here.
>

But the C++ standard states

"in a return statement in a function with a class return type, when
the expression is the name of a
non-volatile automatic object with the same cv-unqualified type as the
function return type, the copy
operation can be omitted by constructing the automatic object directly
into the function�s return value"


Here the type of the destination is 'A' and is not the same as 'B'. So
why does copy constructor elision come into picture?

Dabs.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]