Enlico
Enlico

Reputation: 28520

Confusion between "rvalue" and "rvalue reference" in book

(I searched for [c++] "functional programming in c++" book, which give only 4 unrelevant results.)

I'm reading Functional Programming in C++ from Ivan Čukić, and at page 118 there's a sentence which I'm not sure I've understood. The section is about rvalue and lvalue overloads of member functions, and the sentence is the following, where the second overload is the one using the && reference type qualifier:

The second overload will be called on objects from which you're allowed to stead the data -- temporary objects and other rvalue references.

My doubts are these:

The code below is for support of my understanding.

Indeed, my understanding is that if I say rvalue reference, I'm talking about a function parameter (so it has a name; example: a in the free function f's declaration) declared as rvalue reference to the actual argument, or a variable that I have declared (so it has a name; example: rr) as an rvalue reference to another variable; (fwiw, both referenc-ed entities must be rvalues, otherwise the reference would not bind). In either case, since it has a name, calling the member function f on it, would result in calling the lvalue overload, wouldn't it?

So is there a miswording in the book or am I missing something?

#include <iostream>

struct A {
  void f() &  { std::cout << "lvalue\n"; } // const & in the book, but it shouldn't make any difference
  void f() && { std::cout << "rvalue\n"; }
};

void f(A&& a) { a.f(); } // a is an lvalue (of type rvalue ref to)

int main() {
  A a;          // "normal" object
  A&& rr = A{}; // rvalue reference to a temporary (with life extended)

  a.f();
  A{}.f(); // only here I expect the rvalue overload to be called, and this is the case
  f(A{});
  rr.f();
}

Upvotes: 3

Views: 108

Answers (1)

songyuanyao
songyuanyao

Reputation: 173044

the word in bold really puzzles me, in that the sentence seems meaningful to me only if I remove that word.

I agree. IMO to be more precise the sentence should be

The second overload will be called on objects from which you're allowed to stead the data -- rvalues (prvalues or xvalues).

Rvalue reference is used for types, rvalue is used for value categories, they're independent things. In this case, which overload will be called depends on value category, i.e. the object to be called on is an lvalue or rvalue, which has nothing to do with its type.

the part in italic puzzles me in the first place, as in what else could it be if not a temporary?, but maybe this is just because I still haven't got a firm understanding of what xvalues are;

Yes, xvalues are rvalues too. Given int x = 0; std::move(x) is an xvalue but it's not a temporary.

Upvotes: 1

Related Questions