converting constructor and explicit copy constructor

  • Follow


This is a question about the interaction between converting constructor
and explicit copy constructor when copy-initializing an object.

class C {
public:
    explicit C(const C&) {}
    C(int i) {}
};

int main()
{
    C c1(1);    // no problem
    C c2 = 2;   // Comeau on-line 4.3.3b ok; cygwin gcc 3.3.3 error.
}

c2 is copy-initialized. Semantically, C(int i) will be called
implicitly to convert 2 to a temporary C object, and then C(const C&)
will also be called implicitly to construct c2. But since C(const C&)
is declared as explicit. So this will fail. I think this is the reason
why gcc rejects it.

But Comeau accepts this. Does Comeau do its optimization by directly
calling C(int i) to construct c2 after it checks to see that
C(const C&) is publicly accessible but doesn't care whether it's
explicit or not?

Surely gcc may well legitimately optimize this, but it seems to comply
more strictly with the semantic restriction of the standard.

Which compiler is more compliant with regard to this? Or does the
standard allow both kinds of behavior? Thanks a lot in advance for
your response.


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

0
Reply khoguan (3) 6/4/2005 6:08:40 PM

On 4 Jun 2005 14:08:40 -0400, Khoguan Phuann wrote:

>This is a question about the interaction between converting constructor
>and explicit copy constructor when copy-initializing an object.
>
>class C {
>public:
>    explicit C(const C&) {}
>    C(int i) {}
>};
>
>int main()
>{
>    C c1(1);    // no problem
>    C c2 = 2;   // Comeau on-line 4.3.3b ok; cygwin gcc 3.3.3 error.
>}
>
>c2 is copy-initialized. Semantically, C(int i) will be called
>implicitly to convert 2 to a temporary C object, and then C(const C&)
>will also be called implicitly to construct c2. But since C(const C&)
>is declared as explicit. So this will fail. I think this is the reason
>why gcc rejects it.
>
>But Comeau accepts this. Does Comeau do its optimization by directly
>calling C(int i) to construct c2 after it checks to see that
>C(const C&) is publicly accessible but doesn't care whether it's
>explicit or not?
>
>Surely gcc may well legitimately optimize this, but it seems to comply
>more strictly with the semantic restriction of the standard.
>
>Which compiler is more compliant with regard to this? Or does the
>standard allow both kinds of behavior? Thanks a lot in advance for
>your response.


I think this is an ambiguity in the standard.  
12.3.1/2 says
"An explicit constructor constructs objects just like non-explicit
constructors, but does so only where the direct-initialization syntax
(8.5) or where casts (5.2.9, 5.4) are explicitly used."

C c2 = 2;
does not have direct initialization syntax so an explicit constructor
cannot be used according to 12.3.1/2 - however, it's not clear whether
the restriction on the explicit constructor applies only to the first
phase of copy initialization.

8.5/14 says
"The result of the call (which is the temporary for the constructor
case) is then used to direct-initialize, according to the rules above,
the object that is the destination of the copy-initialization."

so take your pick whether 12.3.1/2 intends that an explicit constructor
be allowed for the direct initialization.  

I think the intent was that the explicit constructor restriction applies
only to the first phase of copy initialization.  GCCs (second) error
message (error initializing temporary) indicates a bug rather than
intentional behaviour since the temporary can bind to the const& just
fine.

Regarding optimisation, the standard does require all semantic
restrictions be respected (12.2/1) even if the copy constructor is not
actually called.

If you change the copy constructor to this
    explicit C( C&) {}
Comeau complains, VC7.1 accepts the code, GCC 3.4.1 gives the same error
messages as before (no matching function; error initializing temporary).

8.5/14 is one of the most problematic sections in the standard for
compilers.  If you want to see some more discussion on this and overload
resolution, have a look at this thread
http://makeashorterlink.com/?D16C2563B

Graeme

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

0
Reply Graeme 6/7/2005 1:59:35 PM


1 Replies
228 Views

(page loaded in 0.045 seconds)

Similiar Articles:













7/25/2012 2:46:09 AM


Reply: