Reputation: 10584
I am wondering if any member function invoked from a rvalue will return a rvalue in c++11 standard.
for example:
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
UPDATE:
if not, it will be very easy to make the mistake below:
decltype(foo()[1]) ai = foo()[1]; //both reference to an obj destroied
decltype(auto) ai = foo()[1];
Upvotes: 1
Views: 63
Reputation: 76240
No, the result of foo()[1]
is an lvalue. According to §3.10:
An lvalue (so called, historically, because lvalues could appear on the left-hand side of an assignment expression) designates a function or an object. [ Example: If E is an expression of pointer type, then *E is an lvalue expression referring to the object or function to which E points. As another example, the result of calling a function whose return type is an lvalue reference is an lvalue. — end example ]
(emphasis mine)
On the other hand you can make it so it returns an rvalue reference in that case, by using:
struct Obj
{
int&& operator[](int i) &&
// ^^
{
return std::move(data_[i]);
// ^^^^^^^^^^ ^
}
int data_[20];
};
or declare the function to be not allowed on r-values by
struct Obj
{
int& operator[](int i) &
// ^^
{
return data_[i];
}
int data_[20];
};
This will now trigger a compile-time error when you do bar()[0]
.
Upvotes: 2
Reputation: 65610
Nope, it'll be an lvalue and if you store a reference to it some place you're on the fast-track to undefined behaviour.
A similar relatively common mistake is storing the result of std::string::c_str()
:
const char* dont_do_this = getStdString().c_str();
Regarding your update code, the solution is to be aware of object lifetimes when you could be creating a reference. decltype(x)
can be a reference type, so you better be sure that if it is, you aren't referencing something which is going to be blasted into oblivion.
Upvotes: 3