繁体   English   中英

与const引用关联的临时对象的生命周期(方法链接)

[英]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引用将是原始对象(只要引用仍然不能保证直播 - 需要一些注意事项)。

为什么会这样? f()的返回值是不是正确的“时间性”类型?

对,不是。 这是一个有点争议的问题:“时间性”的官方定义有点开放。

在最近的编译器中,时间性一直在扩展。 首先,它仅适用于prvalue(非“引用”)表达式,以及应用于此类表达式的成员访问(“点运算符”)。 现在它也适用于强制转换表达式和数组访问。 虽然您可以将移动操作编写为static_cast< T && >( t ) ,这将保留时间性,但只需编写std::move( t )

我正在制定一系列扩展C ++的建议 ,以便您的示例能够按预期工作。 这个功能在C ++ 17中出现的可能性非常小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM