在C++ 03中,表达式是rvalue或lvalue.
在C++ 11中,表达式可以是:
两类已成为五大类.
根据另一个答案,如果引用它的表达式是xvalue表达式,则右值引用不会延长临时值的生命周期.因为std::move返回一个右值引用,所以调用它的表达式是一个xvalue,所以下面的结果是一个悬空引用:
int main()
{
std::string&& danger = std::move(get_string()); // dangling reference !
return 0;
}
Run Code Online (Sandbox Code Playgroud)
没关系.在std::move没有意义在这里; 它已经是一个左值.
但是这里我正在画一个空白.将xvalue表达式作为参数传递,完全标准使用std::move和rvalue引用有何不同?
void foo(const std::string& val);
// More efficient foo for temporaries:
void foo(std::string&& val);
int main()
{
std::string s;
foo(std::move(s)); // Give up s for efficiency
return 0;
}
Run Code Online (Sandbox Code Playgroud)
rvalue引用参数是否有一个特殊规则,它将延长临时的生命周期,无论它是prvalue还是xvalue?或者std::move调用表达式只是一个xvalue,因为我们传递了一个已经是rvalue的东西?我不这么认为,因为它总是返回一个右值引用,这是一个xvalue.我在这里很困惑.我想我错过了一些愚蠢的话.
我想通过引用传递一个struct,因此它不会被复制,但Resharper会在下面给出警告:
struct sometype {
};
sometype foo() {
sometype x;
return x;
}
void bar() {
sometype & a = foo();//Binding r-value to l-value reference is non-standard Microsoft C++ extension
sometype && b = foo(); //ok
}
Run Code Online (Sandbox Code Playgroud)
问题:
怎么了sometype & a = foo();?是不是foo()左值的返回值,a也是左值?
是sometype && b = foo();实际上右值引用?它是否"窃取"返回值foo()并将结果发送b给析构函数?
还有另一种方法没有这个警告吗?
我想知道为什么返回const reference本地对象是非法的,而返回a local object是合法的,只要你将它分配给const reference?
vector<int> f_legal() {
vector<int> tempVec;
tempVec.push_back(1);
return tempVec;
}
const vector<int>& f_illegal() {
vector<int> tempVec;
tempVec.push_back(1);
return tempVec;
}
void g() {
const vector<int>& v1 = f_legal(); // legal
const vector<int>& v2 = f_illegal(); // illegal
}
Run Code Online (Sandbox Code Playgroud)
编辑:我的观点是,如果将const ref赋给返回的局部变量是合法的,那么不应该将const ref分配给局部变量的返回const ref也是合法的吗?
显然,关于这个问题,编译器之间存在一些混淆和差异:
根据这篇文章:
什么是右值、左值、xvalues、glvalues 和 prvalues?
Xvalues 是 rvalues(与 prvalues 一起),标准说:
第二个上下文是引用绑定到临时对象时。引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:
然而,有一些帖子对此提出异议:
什么是非 POD 对象的 xvalue 和 prvalue 之间允许的使用或行为差异的示例?
有人可以澄清这个问题。MSVC 适合一次吗?
遵循这个问题的公认答案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 …