c++ - 生命周期延长、纯右值和缺值

标签 c++ c++11 xvalue prvalue value-categories

遵循这个问题的广为接受的答案 Do rvalue references allow dangling references?当分配给问题中的右值引用左值时,xvalues 似乎没有延长其生命周期。但是当我这样做的时候

#include <iostream>

using namespace std;

class Something {
public:
    Something() {
        cout << "Something()" << endl;
    }
    Something(const Something&) {
        cout << "Something(const Something&)" << endl;
    }
    Something(Something&&) {
        cout << "Something(Something&&)" << endl;
    }
    ~Something() {
        cout << "~Something()" << endl;
    }

    int a;
};

Something make_something() {
    return Something{};
}

int main() {
    auto&& something = make_something().a;

    return 0;
}

通过调用 make_something 返回的对象的生命周期被延长,即使 make_something().a 是一个根据 http://en.cppreference.com/w/cpp/language/value_category 的 xvalue (xvalues 解释中的第三个项目符号列出了我在上面作为 xvalue 拥有的成员访问权限,)

a.m, the member of object expression, where a is an rvalue and m is a non-static data member of non-reference type;

如果值类别不能确定何时延长右值的生命周期,那么什么决定?当在 C++ 中延长右值的生命周期时,我很难理解

最佳答案

生命周期延长不关心值(value)类别。正如 [class.temporary]/p6 所述:

The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference

添加了强调。

这里没有说明所引用表达式的值类别。

决定一个临时文件是否被扩展的正是上述内容(以及更多的规则)。


But that does not explain why adding an std::move() around the temporary to which the reference is being assigned does not extend the lifetime

std::move 不是 C++ 中神奇的、编译器定义的结构。这是一个函数调用,因此它的行为与任何其他 C++ 函数调用没有区别。

那么,如果您有 std::move(Type()),那是什么意思?这意味着您将创建一个临时对象,将其绑定(bind)到 std::move参数,然后调用该函数,该函数将返回一些内容。

如 [class.temporary]/p6 中所述,将临时对象绑定(bind)到函数参数意味着临时对象的生命周期固定为创建它的完整表达式的生命周期(如果不是该规则,则临时对象必须在函数调用结束时销毁,因为那是引用生命周期的结束)。

函数做什么、说什么或暗示什么并不重要。编译器是否可以内联事物并确定返回值是对来自临时变量的参数的引用并不重要。该临时对象的生命周期固定为表达式,而不是延长。

关于c++ - 生命周期延长、纯右值和缺值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42441791/

相关文章:

c++ - 在这种情况下如何创建模板类?

c++ - 为什么 gcc 无法从其前向声明中检测到友元类命名空间?

c++ - 了解 move 构造函数、std::move 和析构函数

c++ - C++ 中的 std::move() 和 xvalue

c++ - 成员函数返回成员变量的右值引用

c++ - 为什么线程随机这么慢,-(或者我的代码哪里错了!)

c# - 拦截 HTTP 请求

c++ - 使用函数指针的 STL 映射

c++ - 作为模板参数 : if(T receive 2 param)T(a, b);否则 T(a);

c++ - xvalue 和 prvalue 之间的一些区别