[英]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 允许显式默认的特殊成员函数
F
的类型T 1
与隐式声明的类型T 2
不同,如下所示:(2.1) —
T 1
和T 2
可能有不同的引用限定符;(2.2)——
T 1
和T 2
可能有不同的例外规范; 和(2.3) — 如果
T 2
有一个const C&
类型的参数,则T 1
的相应参数可能是C&
类型。如果
T 1
与T 2
以任何其他方式不同,则:(2.4) — 如果
F
是赋值运算符,并且T 1
的返回类型与T 2
的返回类型不同或T 1
的参数类型不是引用,则程序格式错误;(2.5) —否则,如果
F
在其第一次声明时被明确默认,则将其定义为已删除;(2.6) — 否则,程序格式错误
任何人都可以提供一个特殊成员函数的示例,该函数明确默认并被编译器删除。 函数声明应该是格式良好的。
来自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 1
( Wrapper
的复制构造函数)与它隐式声明的情况不同(根据[class.copy.ctor]/7本来应该是Wrapper(Wrapper&)
)。 这与第一组项目符号中的情况不匹配(这里T 1
有const&
但没有T 2
,项目符号的顺序相反),所以我们落入第二组项目符号 - 最后我们得到了Wrapper<MyType>
的复制构造函数被删除。
在代码中出现这种情况的一个很好的例子是std::tuple
(参见LWG2086 ),在这些更改之前:
struct A {
A();
A(A&);
};
std::tuple<A> x; // ill-formed
现在,这是格式良好的,只是tuple<A>
不可复制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.