在这段代码中:
#include <iostream> using std::cout; class Foo { public: Foo(): egg(0) {} Foo(const Foo& other): egg(1) {} int egg; }; Foo bar() { Foo baz; baz.egg = 3; return baz; } int main(void) { Foo spam(bar()); cout << spam.egg; return 0; }
输出为3,而我预计为1.
这意味着在Foo垃圾邮件(bar())的行中没有调用复制构造函数.
我猜这是因为bar函数不返回引用.
如果这是一个愚蠢的问题,我提前道歉.
谢谢!
解决方法
复制/移动elision是所谓的“as-if”规则唯一允许的异常,这通常限制了允许编译器对程序执行的变换(例如优化)的种类.
该规则旨在允许编译器执行任何希望的优化,只要转换的程序将工作“好像”是原来的.但是,有一个重要的例外.
根据C11标准第12.8 / 31段:
When certain criteria are met,an implementation is allowed to omit the copy/move construction of a class
object,even if the constructor selected for the copy/move operation and/or the destructor for the object
have side effects. […] This elision of copy/move operations,called copy elision,is permitted in the following circumstances (which
may be combined to eliminate multiple copies):
- in a
return
statement in a function with a class return type,when the expression is the name of a
non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified
type as the function return type,the copy/move operation can be omitted by constructing
the automatic object directly into the function’s return value[…]
- when a temporary class object that has not been bound to a reference (12.2) would be copied/moved
to a class object with the same cv-unqualified type,the copy/move operation can be omitted by
constructing the temporary object directly into the target of the omitted copy/move[…]