9

I just started learning about rvalue references in c++11 by reading this page, but I got stuck into the very first page. Here is the code I took from that page.

  int& foo();
  foo() = 42; // ok, foo() is an lvalue
  int* p1 = &foo(); // ok, foo() is an lvalue

  int foobar();
  j = foobar(); // ok, foobar() is an rvalue
  int* p2 = &foobar(); // error, cannot take the address of an rvalue
  1. why is foo() an lvalue? is it because foo() returns int& which is basically an lvalue?
  2. why is foobar() an rvalue? is it because foobar() returns int?
  3. In general, why would you care if a function is an rvalue or not? I think if I read the rest of that article, I'll get my answer to this.
ildjarn
  • 62,044
  • 9
  • 127
  • 211
aminfar
  • 2,297
  • 3
  • 27
  • 37

1 Answers1

17

L-Values are locations, R-Values are storable values (i.e., values that can be assigned: namespaces, for instance, are not assignable; thanks to @Maggyero for the edit suggestion).

So:

  1. since foo() returns a reference(int&), that makes it an lvalue itself.
  2. Correct. foobar() is an rvalue because foobar() returns int.
  3. We don't care that much if a function is an R-Value or not. What we are getting excited about is R-Value references.

The article you pointed to is interesting and I had not considered forwarding or the use in factories before. The reason I was excited about R-Value references was the move semantics, such as this:

BigClass my_function (const int& val, const OtherClass & valb);

BigClass x;
x = my_function(5, other_class_instance);

In that example, x is destroyed, then the return of my_function is copied into x with a copy constructor. To get around that historically, you would write:

void my_function (BigClass *ret, const int& val, const OtherClass & valb);

BigClass x;
my_function(&x, 5, other_class_instance);

which means that now my_function has side effects, plus it isn't as plain to read. Now, with C++11, we can instead write:

BigClass & my_function (const int& val, const OtherClass & valb);

BigClass x;
x = my_function(5, other_class_instance);

And have it operate as efficiently as the second example.

Marco Ottina
  • 399
  • 5
  • 12
Joshua D. Boyd
  • 4,808
  • 3
  • 29
  • 44
  • 2
    ‘R-Values are actual values’ More precisely, R-values are *storable* values. Some values cannot be assigned in C++ and therefore are not R-values, e.g. a type, a namespace. – Géry Ogam Sep 21 '21 at 12:03
  • @Maggyero namespaces and types aren't values at all. Not everything with a name is a value – Caleth Feb 11 '22 at 16:08
  • @Caleth A value is the meaning of an expression. Since namespaces and types are not meaningless, they do have a value. You may have a look at Dana Scott and Christopher Strachey’s work on denotational semantics. I don’t think that a denotational semantics for C++ has been published though. For the moment it is only specified in natural language in the ISO C++ standard. – Géry Ogam Feb 11 '22 at 16:59
  • @Maggyero the C++ standard talks about values in [basic.lval](https://timsong-cpp.github.io/cppwp/n4861/basic.lval), namespaces and types are not expressions (though namespace names and type names can appear with an expression) "The result of a glvalue is the entity denoted by the expression. The result of a prvalue is the value that the expression stores into its context; a prvalue that has type cv void has no result. A prvalue whose result is the value V is sometimes said to have or name the value V." – Caleth Feb 11 '22 at 17:04
  • @Caleth A [*value*](http://www.cs.ox.ac.uk/files/3232/PRG10.pdf) (or *denotation*) in denotational semantics is what is called an [*entity*](https://timsong-cpp.github.io/cppwp/n4861/basic.pre#3) in the terminology of the ISO C++ standard. And a [*stored value*](http://www.cs.ox.ac.uk/files/3232/PRG10.pdf) (or *stored denotation*) in denotational semantics is what is called a [*value*](https://timsong-cpp.github.io/cppwp/n4861/basic.pre#3) in the ISO C++ standard. Namespaces and types are values in the terminology of denotational semantics and entities in that of the ISO C++ standard. – Géry Ogam Feb 11 '22 at 18:43
  • @Maggyero and we are talking about C++, not denotational semantics. Use the definitions in the C++ standard – Caleth Feb 11 '22 at 22:16
  • @Caleth Yes I should have given more context, sorry for the confusion. – Géry Ogam Feb 11 '22 at 22:43