简体   繁体   中英

An example of a well-formed class definition with a defaulted special member function that the compiler makes deleted

In the C++20 standard, [dcl.fct.def.default] , Explicitly-defaulted functions:

2 The type T 1 of an explicitly defaulted special member function F is allowed to differ from the type T 2 it would have had if it were implicitly declared, as follows:

(2.1) — T 1 and T 2 may have differing ref-qualifiers;

(2.2) — T 1 and T 2 may have differing exception specifications; and

(2.3) — if T 2 has a parameter of type const C& , the corresponding parameter of T 1 may be of type C& .

If T 1 differs from T 2 in any other way, then:

(2.4) — if F is an assignment operator, and the return type of T 1 differs from the return type of T 2 or T 1 '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, T 1 ( 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 T 1 has const& but not T 2 , 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM