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

2023-01-15


1080. Confusing relationship between templates and copy constructors

Section: 11.4.5.3  [class.copy.ctor]     Status: C++11     Submitter: Jason Merrill     Date: 2010-06-19

[Voted into the WP at the March, 2011 meeting.]

11.4.5.3 [class.copy.ctor] paragraphs 6-7 currently read,

A declaration of a constructor for a class X is ill-formed if its first parameter is of type (optionally cv-qualified) X and either there are no other parameters or else all other parameters have default arguments.

A member function template is never instantiated to perform the copy of a class object to an object of its class type. [Example:

    struct S {
        template<typename T> S(T);
        template<typename T> S(T&&);
        S();
    };

    S f();
    const S g;

    void h() {
        S a( f() ); // does not instantiate member template;
                    // uses the implicitly generated move constructor
        S a(g);     // does not instantiate the member template;
                    // uses the implicitly generated copy constructor
    }

These paragraphs were previously a single paragraph, and the second sentence was intended to mean that

    template <class T> A(T):

will never be instantiated to produce A(A). It should not have been split and the example should not have been amended to include move construction.

Lawrence Crowl: I suggest something along the lines of

A member function template is never instantiated to match the signature of an ill-formed constructor.

Proposed resolution (November, 2010):

Merge 11.4.5.3 [class.copy.ctor] paragraphs 6 and 7 and change the text as follows:

A declaration of a constructor for a class X is ill-formed if its first parameter is of type (optionally cv-qualified) X and either there are no other parameters or else all other parameters have default arguments. A member function template is never instantiated to perform the copy of a class object to an object of its class type produce such a constructor signature. [Example:

  struct S {
    template<typename T> S(T);
    template<typename T> S(T&&);
    S();
  };

  S f();
  const S g;

  void h() {
    S a( f() ); // does not instantiate member template;
                // uses the implicitly generated move constructor
    S a(g);     // does not instantiate the member template to produce S::S<S>(S);
                // uses the implicitly generated declared copy constructor
}