为什么即使允许copy-elision发生,代码也需要具有可访问的复制/移动构造函数?

时间:2016-09-12 11:17:39

标签: c++ c++14 language-lawyer copy-elision

Nicol Bolas在his answer的SO中写下了以下内容:

  

在许多情况下允许复制省略。   但是,即使允许,代码仍然必须能够   工作好像副本没有被删除。也就是说,必须有一个   可访问的副本和/或移动构造函数。]

为什么有必要(在#34;保证副本省略出现之前")代码维护复制/移动构造函数,即使允许复制省略发生?

为什么" guaranteed copy elision"程序员从这些要求中解放出来?

4 个答案:

答案 0 :(得分:3)

当标准不保证(或不需要)复制省略时,则不需要编译器来实现它。

这意味着标准允许编译器支持复制省略,但并不要求它们。而且,在实践中,许多编译器供应商选择不实现复制省略。对于那些供应商来说,这只是成本问题 - 没有实现功能会消耗更少的开发人员。对于程序员(使用编译器的人)来说,这是一个实现关注的质量 - 更高质量的编译器更有可能实现理想的优化,包括复制省略,而不是低质量的编译器 - 但是获取的成本也更高。

随着时间的推移,随着更高质量的编译器变得更加自由可用(通过各种“免费”定义 - 并非所有都相当于零成本),逐渐地,该标准能够强制要求以前可选的更多功能。但它没有那样开始。

复制省略是可选的,一些编译器会依赖相关复制构造函数的可访问性等,有些则不会。然而,符合标准要求的代码概念在标准中自然是不合需要的,该代码用一个兼容的编译器而不是另一个编译器构建。因此,该标准要求构造者可以访问,即使在允许实现过程中也是如此。

答案 1 :(得分:1)

为了保证代码能够正常工作,对于无法保证复制省略的每种情况,都必须有一些工作方式,而不需要复制省略。

答案 2 :(得分:1)

因为它是允许的,但不能保证。

如果不需要可访问的拷贝构造函数,某些代码会在优化启动时编译,但在其他编译器上可能会失败。

答案 3 :(得分:0)

  

为什么有必要(在#34;保证副本省略出现之前")代码维护复制/移动构造函数,即使允许复制省略发生?

因为正如其他人所说的那样,只允许省略 copy move 。并非每个编译器都必须省略它,因此为了保持一致性,程序员仍然可以安排复制/移动。从概念上讲,仍然存在复制/移动,无论是否由编译器执行都是一个不同的故事。

  

为什么"保证复制省略"让程序员摆脱这些要求?

因为没有副本或移动开始。保证副本" elision"通过完全改变T a = T()的含义来工作,说T()初始化a而不是临时对象,因此复制或移动构造器在任何时候都不是游戏的一部分。