我想知道从rvalue调用的任何成员函数是否会返回c++11标准中的rvalue。
例如:
Obj foo();
struct Obj
{
int& operator[](int i)
{
return data_[i];
}
int data_[20];
};
foo()[1]; // this expression will be treated as rvalue, right?
// althrough operator[] return a reference更新:
如果不这样做,就很容易犯以下错误:
decltype(foo()[1]) ai = foo()[1]; //both reference to an obj destroied
decltype(auto) ai = foo()[1];发布于 2015-12-16 15:27:16
不,它将是一个独立值,如果您在某个地方存储了对它的引用,那么您就可以快速找到未定义的行为。
一个类似的比较常见的错误是存储std::string::c_str()的结果。
const char* dont_do_this = getStdString().c_str();关于更新代码,解决方案是在创建引用时注意对象的生存期。decltype(x)可以是一个引用类型,所以您最好确保如果它是引用的话,您就不会引用那些即将被遗忘的东西。
发布于 2015-12-16 15:27:52
不,foo()[1]的结果是一个值。根据第3.10节:
lvalue (历史上称为lvalue,因为lvalue可能出现在赋值表达式的左侧)指定函数或对象。示例:如果E是指针类型的表达式,那么*E就是引用E所指向的对象或函数的lvalue表达式。作为另一个例子,调用返回类型为lvalue引用的函数的结果是lvalue. - end示例。
(强调地雷)
另一方面,您可以使它返回一个rvalue引用(在这种情况下),方法是:
struct Obj
{
int&& operator[](int i) &&
// ^^
{
return std::move(data_[i]);
// ^^^^^^^^^^ ^
}
int data_[20];
};或将函数声明为不允许在r-值上使用
struct Obj
{
int& operator[](int i) &
// ^^
{
return data_[i];
}
int data_[20];
};这将在执行bar()[0]时触发编译时错误。
https://stackoverflow.com/questions/34315772
复制相似问题