临时对象有身份吗?

Do Temporary Objects have identity?

我一直在质疑自己 Temporary Objects 是否有 identity。我知道以下是有效的:

object.temporary_object().modify()

只要返回的对象是非常量对象或在对象上调用的函数就不会修改不可变成员。

根据 the value categories definitionprvalues 结果可以 moved 但没有标识,因为临时对象是纯右值表达式,如何修改?

您可以像修改任何其他对象一样修改临时对象。这些修改将毫无意义,因为当临时对象的生命周期结束并被销毁时,它们将被丢弃。

有点像这样的东西:

SomeClass object;
// Some code...

{
    // Entering a new scope, the life-time of variables in here ends when the scope ends
    SomeOtherClass temporary_object = object.temporary_object();

    temporary_object.modify();

    // Now the scope ends, and the life-time of temporary_object with it
}

// Here there exists no such things as "temporary_object"

当嵌套范围结束时,您对 temporary_objects 所做的所有修改都将丢失,并且 temporary_object 被破坏。


一个重要的免责声明:您可以设计 SomeOtherClass(来自上面的示例)以保留 link(引用或指针)到 objectmodify() 函数可以使用 link 来修改 object 本身。 那些修改在temporary_object被破坏后仍然存在,因为它们是对object本身的修改而不是temporary_object

链接文档不规范。在某种意义上,它似乎描述了纯右值应该是什么,而不是它们当时是什么。在 C++17 中,纯右值没有恒等式成为事实——但在 C++11 和 C++14 中,情况并非如此。

在 C++11 和 C++14 中,class 类型的纯右值 有恒等式,因为正如您所观察到的,它可能在其上调用方法,也有观察其地址的方法。类似地,数组类型的纯右值具有恒等式。标量类型的纯右值(例如,整数文字)没有身份。将它们绑定到引用将导致临时对象的具体化,该对象现在有一个地址但不再作为纯右值可观察。

在 C++17 中,纯右值没有标识,也不是临时对象,而是可用于创建临时(或非临时)对象的表达式。从纯右值有效地移动到对象 "invokes" 纯右值。临时对象只能作为 xvalue 观察到。