生命周期延长、纯右值和 xvalues

Cur*_*ous 3 c++ xvalue c++11 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;
}
Run Code Online (Sandbox Code Playgroud)

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

am,对象表达式的成员,其中a是右值,m是非引用类型的非静态数据成员;

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

Nic*_*las 5

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

引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在

加了重点。

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

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


但这并不能解释为什么std::move()在分配引用的临时对象周围添加一个不会延长生命周期

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

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

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

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

  • @Curious:“* std::move() 返回的值的生命周期没有延长。*” 值的生命周期没有延长;值根本没有生命周期*。对象有生命周期,临时对象的生命周期可以延长。`move` 的返回值是一个引用,而不是一个对象。 (4认同)