格式良好的 class 定义示例,其中包含编译器删除的默认特殊成员函数

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

在 C++20 标准中,[dcl.fct.def.default],显式默认函数:

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

(2.1) — T1 and T2 may have differing ref-qualifiers;

(2.2) — T1 and T2 may have differing exception specifications; and

(2.3) — if T2 has a parameter of type const C&, the corresponding parameter of T1 may be of type C&.

If T1 differs from T2 in any other way, then:

(2.4) — if F is an assignment operator, and the return type of T1 differs from the return type of T2 or T1’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

任何人都可以提供一个显式默认的特殊成员函数的示例,该函数已被编译器删除。函数声明应该是格式正确的。

来自P0641的例子,这句话的出处:

struct MyType {
  MyType(MyType&);  // no 'const'
};

template <typename T>
struct Wrapper {
  Wrapper(const Wrapper&) = default;
  T t;
};

Wrapper<MyType> var;  // fails to instantiate

假设实际上有一个默认构造函数。

以前的格式不正确。现在,T<sub>1</sub>Wrapper 的复制构造函数)与它不同,如果它隐式声明(会有Wrapper(Wrapper&)[class.copy.ctor]/7)。这与第一组项目符号中的情况不匹配(这里 T<sub>1</sub>const& 但没有 T<sub>2</sub>,子弹的顺序相反),所以我们落到第二组子弹 - 我们最终得到 Wrapper<MyType>'s正在删除复制构造函数。


代码中会出现这种情况的一个很好的例子是 std::tuple(参见 LWG2086),在这些更改之前:

struct A {
  A();
  A(A&);
};
std::tuple<A> x; // ill-formed

现在,这是合式的,只是 tuple<A> 不可复制。