In the C++20 standard, [dcl.fct.def.default], Explicitly-defaulted functions:
2 The type
T1
of an explicitly defaulted special member functionF
is allowed to differ from the typeT2
it would have had if it were implicitly declared, as follows:(2.1) —
T1
andT2
may have differing ref-qualifiers;(2.2) —
T1
andT2
may have differing exception specifications; and(2.3) — if
T2
has a parameter of typeconst C&
, the corresponding parameter ofT1
may be of typeC&
.If
T1
differs fromT2
in any other way, then:(2.4) — if
F
is an assignment operator, and the return type ofT1
differs from the return type ofT2
orT1
’s parameter type is not a reference, the program is ill-formed;(2.5) — otherwise, if
F
is explicitly defaulted on its first declaration, it is defined as deleted;(2.6) — otherwise, the program is ill-formed
Could anybody provide an example of a special member function explicitly defaulted and that is deleted by the compiler. The function declaration should be well-formed.
The example from P0641, whence this wording:
struct MyType {
MyType(MyType&); // no 'const'
};
template <typename T>
struct Wrapper {
Wrapper(const Wrapper&) = default;
T t;
};
Wrapper<MyType> var; // fails to instantiate
Pretend there was actually a default constructor.
This was previously ill-formed. Now, T1
(Wrapper
's copy constructor) differs from it what it would have been were it implicitly declared (would have been Wrapper(Wrapper&)
per [class.copy.ctor]/7). This doesn't match the cases in the first set of bullets (here T1
has const&
but not T2
, the bullet is in the opposite order), so we fall through to the second set of bullets - and we end up with Wrapper<MyType>
's copy constructor being deleted.
A good example of where this would've come up in code is something like std::tuple
(see LWG2086), where prior to these changes:
struct A {
A();
A(A&);
};
std::tuple<A> x; // ill-formed
Now, this is well-formed, just that tuple<A>
isn't copyable.