在这段代码中:
#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[…]
换句话说,在12.8 / 31条款适用的情况下,你不应该依赖于被调用或不被调用的构造函数或移动构造函数.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。