首页 > 解决方案 > 具有编译器删除的默认特殊成员函数的格式良好的类定义示例

问题描述

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

2显式默认的特殊成员函数的类型允许与隐式声明时的类型不同,如下所示:T1FT2

(2.1) —并且可能有不同的 ref-qualifiers;T1T2

(2.2) —并且可能有不同的异常规范;和T1T2

(2.3) — 如果有一个类型的参数,则对应的参数可能是类型。T2const C&T1C&

如果与任何其他方式不同,则:T1T2

(2.4) — ifF是一个赋值运算符,并且返回类型 不同于or的返回类型的参数类型不是引用,程序是非良构的;T1T2T1

(2.5) —否则,如果F在其第一个声明中明确默认,则将其定义为已删除;

(2.6) — 否则,程序格式错误

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

标签: c++classdefaultc++20function-definition

解决方案


来自P0641的示例,由此措辞:

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

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

Wrapper<MyType> var;  // fails to instantiate

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

这是以前格式错误的。现在,(的复制构造函数) 与隐式声明的情况不同(按照[class.copy.ctor]/7的情况)。这与第一组项目符号中的情况不匹配(这里有但不是,项目符号的顺序相反),所以我们进入第二组项目符号 - 我们最终删除了 的复制构造函数.T1WrapperWrapper(Wrapper&)T1const&T2Wrapper<MyType>


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

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

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


推荐阅读