This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


535. Copy construction without a copy constructor

Section: 11.4.5.3  [class.copy.ctor]     Status: CD3     Submitter: Mike Miller     Date: 7 October 2005

[Voted into the WP at the February, 2012 meeting; moved to DR at the October, 2012 meeting.]

Footnote 112 (11.4.5.3 [class.copy.ctor] paragraph 2) says,

Because a template constructor is never a copy constructor, the presence of such a template does not suppress the implicit declaration of a copy constructor. Template constructors participate in overload resolution with other constructors, including copy constructors, and a template constructor may be used to copy an object if it provides a better match than other constructors.

However, many of the stipulations about copy construction are phrased to refer only to “copy constructors.” For example, 11.4.5.3 [class.copy.ctor] paragraph 14 says,

A program is ill-formed if the copy constructor... for an object is implicitly used and the special member function is not accessible (11.8 [class.access]).

Does that mean that using an inaccessible template constructor to copy an object is permissible, because it is not a “copy constructor?” Obviously not, but each use of the term “copy constructor” in the Standard should be examined to determine if it applies strictly to copy constructors or to any constructor used for copying. (A similar issue applies to “copy assignment operators,” which have the same relationship to assignment operator function templates.)

Proposed Resolution (August, 2011):

  1. Change 6.3 [basic.def.odr] paragraph 2 as follows:

  2. ...[Note: This covers calls to named functions (7.6.1.3 [expr.call]), operator overloading (Clause 12 [over]), user-defined conversions (11.4.8.3 [class.conv.fct]), allocation function for placement new (7.6.2.8 [expr.new]), as well as non-default initialization (9.4 [dcl.init]). A copy constructor or move constructor selected to copy or move an object of class type is odr-used even if the call is actually elided by the implementation (11.4.5.3 [class.copy.ctor]). —end note] ... A copy-assignment function for a class An assignment operator function in a class is odr-used by an implicitly-defined copy-assignment or move-assignment function for another class as specified in 11.4.5.3 [class.copy.ctor]. A move-assignment function for a class is odr-used by an implicitly-defined move-assignment function for another class as specified in 11.4.5.3 [class.copy.ctor]. A default constructor...
  3. Delete 11.4.5 [class.ctor] paragraph 9:

  4. A copy constructor (11.4.5.3 [class.copy.ctor]) is used to copy objects of class type. A move constructor (11.4.5.3 [class.copy.ctor]) is used to move the contents of objects of class type.

  5. Change 6.7.7 [class.temporary] paragraph 1 as follows:

  6. ...[Note: even if there is no call to the destructor or copy/move constructor, all the semantic restrictions, such as accessibility (11.8 [class.access]) and whether the function is deleted (9.5.3 [dcl.fct.def.delete]), shall be satisfied. this includes accessibility (11.8 [class.access]) and whether it is deleted, for the constructor selected and for the destructor. However, in the special case of a function call...
  7. Change 11.4.5.3 [class.copy.ctor] paragraph 13 as follows:

  8. A copy/move constructor that is defaulted and not defined as deleted is implicitly defined if it is odr-used (6.3 [basic.def.odr]) to initialize an object of its class type from a copy of an object of its class type or of a class type derived from its class type [Footnote: See 9.4 [dcl.init] for more details on direct and copy initialization. —end footnote] or when it is explicitly defaulted...

  9. Change 11.4.5.3 [class.copy.ctor] paragraph 31 as follows:
  10. When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor selected for the copy/move operation and/or the destructor for the object have side effects...
  11. Change 12.2.4.2.3 [over.ics.user] paragraph 4 as follows:

  12. A conversion of an expression of class type to the same class type is given Exact Match rank, and a conversion of an expression of class type to a base class of that type is given Conversion rank, in spite of the fact that a copy/move constructor (i.e., a user-defined conversion function) is called for those cases.
  13. Change 14.2 [except.throw] paragraph 3 as follows:

  14. A throw-expression copy-initializes (9.4 [dcl.init]) a temporary object, called the exception object...
  15. Change 14.2 [except.throw] paragraph 5 as follows:

  16. When the thrown object is a class object, the copy/move constructor selected for the copy-initialization and the destructor shall be accessible, even if the copy/move operation is elided (11.4.5.3 [class.copy.ctor]).

[Drafting note: 7.6.19 [expr.ass] paragraph 4, Clause 11 [class] paragraph 4, 11.5 [class.union] paragraph 1, 6.7.7 [class.temporary] paragraph 2, 11.4.5.3 [class.copy.ctor] paragraphs 1-2, and 14.5 [except.spec] paragraph 14 do not require any changes.]