explicit copy constructors
15.3.1 [class.conv.ctor]
Steve Adamczyk

Created on 1999-08-04.00:00:00 last changed 208 months ago


Date: 2001-04-15.00:00:00

Proposed resolution (04/01):

  1. Change the first two sentences of [over.match.ctor] paragraph 1 to

    When objects of class type are direct-initialized (11.6 [dcl.init]), or copy-initialized from an expression of the same or a derived class type (11.6 [dcl.init]), overload resolution selects the constructor. For direct-initialization, the candidate functions are all the constructors of the class of the object being initialized. For copy-initialization, the candidate functions are all the converting constructors (15.3.1 [class.conv.ctor] ) of that class.
  2. Change the first sentence of 15.3.1 [class.conv.ctor] paragraph 3 to read:

    A non-explicit copy constructor (15.8 [class.copy]) is a converting constructor.
Date: 2001-04-15.00:00:00

Notes from 04/01 meeting:

After the issue was accepted as a DR with the proposed resolution to change [over.match.ctor] paragraph 1 as described below, it was noticed that 15.3.1 [class.conv.ctor] paragraph 3 states that:

A copy-constructor (15.8 [class.copy]) is a converting constructor.

In addition to making the proposed resolution for this issue ineffectual, the wording of paragraph 3 also contradicts that of paragraph 1:

A constructor declared without the function-specifier explicit that can be called with a single parameter specifies a conversion from the type of its first parameter to the type of its class. Such a constructor is called a converting constructor.

These considerations led to the addition of the second point of the proposed resolution.

Date: 2004-09-10.00:00:00

Can a copy-constructor declared as explicit be used to copy class values implicitly? For example,

   struct X {
      explicit X(const X&);
   void f(X);
   int main() { X x; f(x); }
According to 15.3.1 [class.conv.ctor] paragraphs 2-3,
An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax (11.6 [dcl.init] ) or where casts (8.2.9 [expr.static.cast] , 8.4 [expr.cast] ) are explicitly used... A copy-constructor (15.8 [class.copy] ) is a converting constructor. An implicitly-declared copy constructor is not an explicit constructor; it may be called for implicit type conversions.
This passage would appear to indicate that the call in the example is ill-formed, since it uses neither the direct-initialization syntax nor an explicit cast. The last sentences are especially interesting in this regard, indicating that explicit and non-explicit copy constructors are handled differently.

On the other hand, 11.6 [dcl.init] paragraph 14, bullet 4, sub-bullet 2 says,

If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination... [the] applicable constructors are enumerated ( [over.match.ctor] )...
The cited passage says that
The candidate functions are all the constructors of the class of the object being initialized.
Date User Action Args
2003-04-25 00:00:00adminsetstatus: dr -> tc1
2001-05-20 00:00:00adminsetmessages: + msg518
2000-11-18 00:00:00adminsetstatus: ready -> dr
2000-05-21 00:00:00adminsetstatus: review -> ready
2000-02-23 00:00:00adminsetmessages: + msg228
2000-02-23 00:00:00adminsetstatus: open -> review
1999-08-04 00:00:00admincreate