3

I have read this and this, but I still do not understand why the following code compiles in XCode:

void func2(string &s) {
    s = "yyyyy";
}

void func(string &&s) {
    func2(s);
}

int main() {
    func("xxxxx");
    return 0;
}

I think an rvalue reference shouldn't be converted to a non-const lvalue reference, right? In general, what's the rule of conversion between lvalue references and rvalue references? I already know that const lvalue reference can bind to rvalues, but what about rvalue references (rather than rvalues)? Thanks a lot!

Community
  • 1
  • 1
Yunsheng Bai
  • 219
  • 4
  • 15

1 Answers1

3

The r-value reference is a reference to the original object, so converting it to a l-value reference will just make a reference to the original object.
Once a move constructor is called upon the reference, the original object should be reset to the origin state, and so does any reference to it.

This example might clarify it:

#include <iostream>
using namespace std;

int main()
{
    string s = "my string";
    string &&rval = move(s);
    cout << '"' << rval << '"' << endl; // "my string"
    cout << '"' << rval << '"' << endl; // "my string"
    cout << '"' << s << '"' << endl;    // "my string"
    string &lval = rval;
    cout << '"' << lval << '"' << endl; // "my string"
    string s2(move(rval));
    cout << '"' << rval << '"' << endl; // ""
    cout << '"' << lval << '"' << endl; // ""
    cout << '"' << s << '"' << endl;    // ""
    cout << '"' << s2 << '"' << endl;   // "my string"
    return 0;
}
Daniel
  • 30,896
  • 18
  • 85
  • 139
  • I think adding ```string &lval = rval; cout << '"' << lval << '"' << endl; // "my string"``` to the example will be more helpful for me to understand. Does it mean an r ref can be implicitly converted to an l ref? However, the opposite is false, because I need to explicitly say move(s) to convert an l ref to an r ref? – Yunsheng Bai Jun 19 '16 at 17:24
  • 2
    "Once a move constructor is called upon the reference, the original object should be reset to the origin state" It's not guaranteed to work this way. – cpplearner Jun 19 '16 at 20:25