其他分享
首页 > 其他分享> > c – 生命周期扩展,prvalues和xvalues

c – 生命周期扩展,prvalues和xvalues

作者:互联网

遵循这个问题的公认答案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是一个xvalue,按照http://en.cppreference.com/w/cpp/language/value_category(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;

如果值类别不确定rvalue的生命周期何时会延长那么呢?我很难理解r值的寿命何时在C中延长

解决方法:

终身扩展不关心价值类别.如[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()),那是什么意思?这意味着你将创建一个临时的,将它绑定到std :: move的参数,然后调用该函数,它将返回一些东西.

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

无论函数是做什么,说什么或暗示什么都没关系.如果编译器可能内联并确定返回值是对来自临时的参数的引用,则无关紧要.临时的生命周期固定在表达式上,而不是扩展.

标签:c,c11,xvalue,value-categories,prvalue
来源: https://codeday.me/bug/20191007/1863905.html