C ++: returns L-value?

Consider this code:

struct foo { int a; }; foo q() { foo f; fa =4; return f;} int main() { foo i; ia = 5; q() = i; } 

No compiler complains about this, not even Clang. Why is the string q() = ... true?

+64
c ++ lvalue return-value
May 24 '11 at 14:21
source share
3 answers

No, the return value of a function is an l-value if and only if it is a reference (C ++ 03). (5.2.2 [expr.call] / 10)

If the return type was basic, then this will be a compilation error. (5.17 [expr.ass] / 1)

The reason for this is that you are allowed to call member functions (even non- const member functions) on r-values โ€‹โ€‹of the class type, and the purpose of foo is a specific implementation member function: foo& foo::operator=(const foo&) . The restrictions for operators in Section 5 apply only to built-in operators (5 [expr] / 3), if overload resolution selects an overloaded function call for an operator, then the restrictions for this function call apply instead.

That is why it is sometimes recommended to return class type objects in the form of const objects (for example, const foo q(); ), however this can have a negative effect on C ++ 0x, where it can interfere with the movement semantics, as they should.

+60
May 24 '11 at 2:26 pm
source share

Since structs can be assigned, and your q() returns a copy of struct foo , therefore it assigns the returned structure to the provided value.

In this case, this is really not the case, because after this the structure goes out of scope, and at first you do not refer to it, therefore, in any case, you cannot do anything with it (in this specific code).

This makes more sense (although still not a โ€œbest practiceโ€)

 struct foo { int a; }; foo* q() { foo *f = new malloc(sizeof(foo)); f->a = 4; return f; } int main() { foo i; ia = 5; //sets the contents of the newly created foo //to the contents of your i variable (*(q())) = i; } 
+8
May 24 '11 at 14:24
source share

One interesting application:

 void f(const std::string& x); std::string g() { return "<tag>"; } ... f(g() += "</tag>"); 

Here g() += changes the temporary, which can be faster, creating an additional temporary event with + , because the heap allocated for the return value of g () may already have enough spare capacity to accommodate </tag> .

See how it launches on ideone.com using GCC / C ++ 11 .

Now, what computer novice said something about optimizations and evil ...?; -.]

+4
May 25 '11 at 4:12
source share



All Articles