链接 https://cplusplus.github.io/LWG/issue2067 提供了以下讨论:
有人可以解释标记语句的含义吗?我不明白缺少的 const 限定符如何影响编译过程,以及如何在标准中解释这种行为。
在删除的复制构造函数的参数中添加 const 有什么意义?
最佳答案
这是一个 toy example :
struct problem {
problem()=default;
problem(problem&&)=default;
problem(problem&)=delete;
};
template<class T>
struct bob {
T t;
bob()=default;
bob(bob&&)=default;
bob(bob const&)=default;
};
int main() {
problem p;
problem p2 = std::move(p);
bob<problem> b;
bob<problem> b2 = std::move(b);
}
bob<problem>
无法编译,因为 bob(bob const&)=default
在与 problem(problem&)=delete
交互时出错。可以说,标准“应该”在确定它不能实现
bob(bob const&)
时干净利落地出错,并将 =default
视为 =delete
(就像我们有 problem(problem const&)=delete
一样),但标准措辞在这种极端情况下不会完美无缺一个角落的情况。一个角落案例的这个角落将变得足够奇怪和古怪,以至于我不确定将 =default
转换为 =delete
的一般规则是正确的!如果我们
problem(problem const&)=delete
(嗯,到 packaged_task
)的修复将比我们对 =default
ctor 规则所做的任何事情都要干净得多。现在标准挖掘:
首先,很明显,上面隐式声明的
bob<problem>
的复制构造函数将在 [class.ctor] 中有签名 bob(bob&)
。我什至不会引用标准,因为懒惰。我们去显式默认
bob(bob const&)
copy ctor,它的签名与隐式声明的签名不同。有关于显式默认函数的规则,它们与签名的冲突在 11.4.2 中。
在显式默认函数中[dcl.fct.def.default] 11.4.2/2
默认的一个是
T1
,它包含 const&
而不是 &
,所以 (2.2) 不适用。我的阅读实际上已经被捕获了(2.4);
bob(bob const&)
的类型与隐式声明的 bob(bob&)
以不允许的方式不同;但是第一个声明是 default
ed,所以它应该是 delete
d。我在看 n4713 draft version ;也许旧版本没有该条款。
关于c++ - std::packaged_task 应该删除了带有 const 参数的拷贝 c'tor,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59841698/