Reputation: 171
We have the following code example:
// lvalues:
//
int i = 42;
i = 43; // ok, i is an lvalue
int* p = &i; // ok, i is an lvalue
int& foo();
foo() = 42; // ok, foo() is an lvalue
int* p1 = &foo(); // ok, foo() is an lvalue
// rvalues:
//
int foobar();
int j = 0;
j = foobar(); // ok, foobar() is an rvalue
int* p2 = &foobar(); // error, cannot take the address of an rvalue
j = 42; // ok, 42 is an rvalue
I'm trying to understand why does a plain function definition as this:
int foobar();
is supposed to be an rvalue, while the same function but with an object reference as the return type, as this:
int& foobar();
is an lvalue. (The second part somehow comes naturally, because we specifically ask for and thus keep a reference when defining the function. However, the first example is hard to grasp for me, as I was expecting that the memory location of a function is somehow implicitly deducted, based on the assumption -that might be wrong-, that each function has its own, non changeable location in memory and, in conclusion, the first example should have also been an lvalue reference). Please try and explain this aspect, first.
I understand that:
An lvalue is an expression that refers to a memory location and allows us to take the address of that memory location via the & operator. An rvalue is an expression that is not an lvalue.
However, as stated above, I'm mostly interested in how functions, as opposed to or in correlation to simple objects, are treated regarding the lvalue/rvalue concept.
Thank you!
Upvotes: 0
Views: 280
Reputation: 75698
foobar()
is not a function. It's a function call. The evaluation of it is the result of calling the function, i.e. an int
which is an rvalue.
Here is how you would assign the function to a reference (which is a better test than taking its address):
int (&a)() = foo; // OK
int (&&b)() = foo; // OK
This is how you would assign the function address
int (*a)() = &foo; // OK
I understand that: "An lvalue is an expression that refers to a memory location and allows us to take the address of that memory location via the & operator. An rvalue is an expression that is not an lvalue."
Well... that's a pretty simplistic definition. Here are some links if you are interested in the subject:
What are rvalues, lvalues, xvalues, glvalues, and prvalues?
Upvotes: 4