链接 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/

10-13 06:29