[英]Lifetime of temporary object associated with const reference (method chaining)
考虑以下代码snipet:
#include <iostream>
struct S {
~S() { std::cout << "dtor\n"; }
const S& f(int i) const { std::cout << i << "\n"; return *this; }
};
int main() {
const S& s = S();
s.f(2);
}
输出 :
2
dtor
即对象的生命周期通过引用扩展,这在Herb的文章中有所解释。
但是,如果我们只更改一行代码并写入:
const S& s = S().f(1);
f(2)
对已经被破坏的物体的召唤:
输出 :
1
dtor
2
为什么会这样? f()
的返回值是不是正确的“时间性”类型?
当你写一个函数时......
const S& f(int i) const { std::cout << i << "\n"; return *this; }
...您正在指示编译器返回const S&
并且您负责确保引用的对象具有适合调用者使用的生命周期。 (“确保”可能构成记录客户使用情况,与您的设计一致。)
常-用代码的典型分离成头和实现文件- f(int) const
的实现甚至不会是调用代码可见,而在这种情况下,编译器对于其中没有洞察S
可能会返回一个参考,也不是S
是暂时的还是暂时的,所以没有依据可以决定是否需要延长寿命。
除了显而易见的选项(例如,信任客户端编写安全代码,按值或智能指针返回),值得了解一个更加模糊的选项......
const S& f(int i) const & { ...; return *this; }
const S f(int i) const && { ...; return *this; }
&
和&&
紧接在函数体之前重载f
,使得如果*this
是可移动的,则使用&&
版本,否则使用&
version。 这样,将一个const &
to f(...)
绑定到一个到期对象上的人将绑定到该对象的新副本,并且根据本地const
引用延长生命周期,而当该对象未到期时( ) const
引用将是原始对象(只要引用仍然不能保证直播 - 需要一些注意事项)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.