为什么该标准允许我的编译器即使在涉及可见副作用的情况下也可以应用复制省略,从而违反了常规规则?
当我保证复制删除时,这在某种程度上对我来说是合理的,因为复制/移动的实际功能(会调用程序行为的可见更改)不一定必须存在,但是这是为什么/如何在C ++ 17之前?
是因为编译器通常无法检测到副作用(我不知道这是否可能)吗?
答案 0 :(得分:4)
允许进行此优化的案例涉及临时副本。从概念上讲,这些应该没有可见的作用,但是该语言允许类编写者将所需的任何内容放入复制构造函数中。
因此,复制构造函数有时可能实际上具有明显的副作用。严格来说,按原样的规则可能不适用。
人们认为这种优化是足够有用的,其危害也很小,值得在语言中包括在内。考虑到此优化早于将返回值将始终被复制的语义移动了。
答案 1 :(得分:2)
即使事情显然是正确的(无论它们是否正确),也很难证明。使编译器能够在可接受的时间内证明事物更加困难。然后一些副作用可能实际上并不重要,但是您将如何告知编译器?
尽管复制删除 不应违反“按原样”规则(至少如果编译器知道在分析中忽略哪些副作用),程序员仍可以自由地编写其类型所以还是可以。
最后,未能证明在特定情况下应用复制删除不会违反现成规则可能会非常昂贵,因为可能会任意涉及创建对象的副本,这需要时间和空间。
因此,复制删除是按规则的例外情况,无论如何都可以被允许。
现在关于保证复制删除,必须承认规则不一定完全显而易见。因此,在性能要求不是太严格的情况下,对性能而言,仅依赖于它是(?)是一件好事,而不是正确性。