Search code examples
c++language-lawyercopy-constructorvolatile

Why is it impossible to explicitly default a copy constructor with volatile argument?


I could not find where in the standard it is stated that it is forbidden to explicitly default a copy-constructor and copy-assignment with a volatile& or const volatile& argument, like this:

struct A{
   A(const volatile A&) =default; // fails to compile on (all) compilers
   };

In [dcl.fct.def.default] there is no such a restriction, while [class.copy] specifies that A(const volatile A&) is a copy constructor.

Note: I am just looking for the location in the text of the standard which specifies this behavior.


Solution

  • You are in the right sections, but are overlooking some crucial bullets.

    [dcl.fct.def.default]/1:

    A function definition of the form:

    ...

    is called an explicitly-defaulted definition. A function that is explicitly defaulted shall

    • have the same declared function type (except for possibly differing ref-qualifiers and except that in the case of a copy constructor or copy assignment operator, the parameter type may be “reference to non-const T”, where T is the name of the member function's class) as if it had been implicitly declared, and

    [class.copy.ctor]/7:

    The implicitly-declared copy constructor for a class X will have the form

    X::X(const X&)
    

    if each potentially constructed subobject of a class type M (or array thereof) has a copy constructor whose first parameter is of type const M& or const volatile M&.119 Otherwise, the implicitly-declared copy constructor will have the form

    X::X(X&)
    

    ...
    119) This implies that the reference parameter of the implicitly-declared copy constructor cannot bind to a volatile lvalue;

    When the above is summed up, your only two options for explicitly defaulting a copy c'tor are these:

    struct A {
       A(const A&) = default;
    };
    
    struct B {
       B(B&) = default;
    };
    

    When the standard says A(const volatile A&) is a copy constructor. It means that a user-provided c'tor with such a parameter can be the classes copy c'tor.