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

2024-11-11


2837. Instantiating and inheriting by-value copy constructors

Section: 11.4.5.3  [class.copy.ctor]     Status: open     Submitter: Brian Bi     Date: 2023-11-29

(From submission #474.)

Subclause 11.4.5.3 [class.copy.ctor] paragraph 5 specifies:

A declaration of a constructor for a class X is ill-formed if its first parameter is of type cv X and either there are no other parameters or else all other parameters have default arguments. A member function template is never instantiated to produce such a constructor signature.

It is unclear what happens when such a constructor signature is inherited from a base class. Also, the wording "never instantiated" is not detailed enough.

Suggested resolution:

  1. Add a paragraph before 9.9 [namespace.udecl] paragraph 13 as follows:

    The set of declarations named by a using-declarator that inhabits a class C does not include any constructor whose first parameter has type cv C and all of whose remaining parameters (if any) have default arguments.

    Constructors that are named by a using-declaration are treated as though they were constructors of the derived class ...

  2. Change in 11.4.5.3 [class.copy.ctor] paragraph 5 as follows:

    A declaration of a constructor for a class X is ill-formed if its first parameter is of type cv X and either there are no other parameters or else all other parameters have default arguments. A member function template is never instantiated to produce such a constructor signature. During type deduction for a constructor template of X (13.10.3.1 [temp.deduct.general]), if substitution produces such a constructor signature, type deduction fails. [ Example 5:
      struct S {
        template<typename T> S(T);
        S();
      };
      S g;
      void h() {
        S a(g);  // does not instantiate the member template to produce S::S<S>(S); no candidate generated from the member template;
                 // uses the implicitly declared copy constructor is used
      }
    
    -- end example]