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