1

i ran the code as shown and i am confused as to why a+b is a rvalue. From what i know, rvalue should only have a data or address and in such a case std::string should be a lvalue isn't it?


void foo(const std::string&& input){
    std::cout<<"RVALUE "<<input<<std::endl;
}
void foo(const std::string& input){
    std::cout<<"LVALUE "<<input<<std::endl;
}

int main(){
    std::string a = "Tom";
    std::string b = "Cruise"; 
    std::string c = a + b;
    foo(a+b);
    foo(c);
}

OUTPUT

 RVALUE TomCruise 
 LVALUE TomCruise
Iberico
  • 162
  • 2
  • 15
  • 1
    Brief intuition: Could you put `a + b` on the left hand side of an assignment statement? Would it make sense to say `(a + b) = "anotherString";`? No. The fully elaborated rules for what goes in which value category when are complex, but thinking about the left and right hand side of assignment statements is a good start. – Nathan Pierson May 14 '21 at 03:25
  • 1
    `a + b` creates a temporary, which is then assigned to `c` or passed to `foo()`. That temporary is an rvalue – Remy Lebeau May 14 '21 at 04:08
  • 1
    _"From what i know, rvalue should only have a data or address"_ — That doesn't make any sense. What does it mean that an rvalue _has something_? – Daniel Langr May 14 '21 at 04:29
  • @NathanPierson Sure you can: https://godbolt.org/z/Knx34avEb. (You can call member functions on rvalues, and `operator=` is also a member function, though special.) – Daniel Langr May 14 '21 at 04:30
  • Well, huh, that's news to me. What is that actually doing? – Nathan Pierson May 14 '21 at 04:34
  • @NathanPierson Calling a member function (`operator=`) on a temporary. – Daniel Langr May 14 '21 at 04:35
  • I suppose it lets you do something like `std::string c = ((a + b) = "Charlie");` and there's no compelling reason to go out of your way to disable `operator=` when the LHS is an rvalue. Peculiar. – Nathan Pierson May 14 '21 at 04:39
  • @NathanPierson See https://stackoverflow.com/a/5890644/580083. But typically, no one does this. There is simply no obvious reason for it. – Daniel Langr May 14 '21 at 04:42
  • Yes, I knew it was possible to do that. I didn't know that `std::string` _didn't_. – Nathan Pierson May 14 '21 at 04:43
  • @NathanPierson A think there is simply no reason for this. Also, ref-qualifiers for member functions are available since C++11. Restricting `operator=` only for lvalues could therefore make older code non-compilable. – Daniel Langr May 14 '21 at 04:50
  • Yes, as I said I suppose there wasn't a compelling reason to disable it. You might choose to do so if you were writing `std::string` from scratch today with C++11 features in hand, or you might not, but you definitely wouldn't go back and overturn years of functioning (if obscure) code. – Nathan Pierson May 14 '21 at 04:52
  • @DanielLangr you can assign a reference of rvalues to lvalues which kind of mean it can contain an address doesn't it? end of the day data or address is just a number. If it has both address and data, it would be a lvalue wouldn't it? – Iberico May 14 '21 at 07:45
  • @Shane Don't understand. What is _"a reference of rvalues"_? Do you mean an _rvalue reference_. If so, you **can't bind it to an lvalue**. Such that `std::string s; std::string&& rs = s;` won't compile. – Daniel Langr May 14 '21 at 11:10

0 Answers0