Skip to content

CWG2837 [class.copy.ctor] Issues with by-value copy constructors #474

Open

Description

@t3nsor

Full name of submitter: Brian Bi

Reference (section label): [class.copy.ctor], [namespace.udecl]

Issue description: [class.copy.ctor]/5 states:

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.

This wording does not explain what happens if such a constructor signature is inherited from a base class; MSVC currently treats the using-declaration as ill-formed (https://godbolt.org/z/6x47rf4vT). We should say that such a constructor is excluded from the inherited set.

Also, the wording "never instantiated" doesn't explain at what step of the process instantiation stops. I doubt there would be any implementation divergence, but even still, we should be a bit more explicit and say the result is a substitution failure.

Suggested resolution:

Add a paragraph before [namespace.udecl]/13:

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 (possibly none) have default arguments.

Edit [class.copy.ctor]/5:

A declaration of a constructor for a class X is ill-formed if its first parameter is of type 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 ([temp.deduct.general]), if substitution produces such a constructor signature, type deduction fails.

In Example 5 to [class.copy.ctor]/5, edit the comment:

// does not instantiate the member template to produce S​::​S<S>(S); no S::S<S>(S) candidate generated from the member template;
// uses the implicitly declared copy constructor is used

Activity

  1. jensmaurer commented on Dec 12, 2023

    @jensmaurer
    Member
  2. changed the title [-][class.copy.ctor] Issues with by-value copy constructors[/-] [+]CWG2837 [class.copy.ctor] Issues with by-value copy constructors[/+] on Dec 12, 2023
  3. t3nsor commented on Dec 13, 2023

    @t3nsor
    Author

    Oh, I also noticed that Clang has something like this in its testsuite:

    template <class T, class U>
    struct X {
        X() = default;
        X(X<T, T>);
    };
    int main() {
        X<int, int> x;
    }
    

    EDG, GCC, and MSVC all reject due to the current [class.copy.ctor]/5. Clang accepts and (I believe) simply treats X<int,int>::X(X<int, int>) as excluded from overload resolution. We might want to consider whether we want the Clang behavior in this case.

  4. hubert-reinterpretcast commented on Jun 12, 2024

    @hubert-reinterpretcast
    Member

    During type deduction for a constructor template of X ([temp.deduct.general]), if substitution produces such a constructor signature, type deduction fails.

    That proposed wording is still wrong: A signature does not include default arguments. Also, (except for MSVC) implementations do not reject instantiating such constructor specializations for uses where the argument list has more than one argument (and that is probably the right thing).

    https://godbolt.org/z/48Ghsoebc

    struct A {
      template <typename T> A(T, int = 0);
      A(const A &) = default;
      A() = default;
    };
    
    A a(A{}, 42);  // OK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions