Rvalue References in C++11

Posted: July 8, 2012 in C++
Tags: , ,

The terms Lvalue & Rvalue has been there since the days of C but still their definition as found in many literature is not very uniform.Before even discussing about the what Rvalue references are in C++11 we need some discussion to get these clarified in the first place.

Any object is nothing but a area in the memory and we need a name to access that memory area from our program. This named and accessible storage area are the objects and variables. These named objects and references are known  as the Lvalues, the name is so because they can appear in the left hand side of an assignment expression.However every Lvalue cannot appear in the left hand side of an assignment as Lvalue can also refer to a constant.So to differentiate sometimes we use the term as modifiable Lvalues.

Following are the examples of Lvalue references:

int i=10; 
string s = "Hello";  

The & reference operator we use in C++ actually a Lvalue reference. The following line of code will throw a compilation error:

string& s1 = "Hello";

error: invalid initialization of non-const reference of type ‘std::string& {aka std::basic_string<char>&}’ from an rvalue of type ‘const char*’

Here s1 is a Lvalue reference and error we are getting says that it cannot bind a Rvalue reference to a non-constant (Lvalue) reference. But before we proceed further it’s now high time to formally introduce the Rvalues. These are things whose address is (was till C++11) not accessible by the program, unnamed temporary objects. In the above example “Hello” is a Rvalue as we need to create a temporary string object for this. So it’s quite obvious that assignment/binding a of Rvalue to a Lvalue reference is failing.

In C++11 we have now Rvalue references which enables us to access these temporary unnamed objects as well. The Rvalue references are denoted with && operator as T&&. So the following line of code compiles without any error:

string& s1 = "Hello";

Also the following line works fine:

const string&& s1 = "Hello";

So an Rvalue can bind to

  • A constant Lvalue reference
  • A RValue reference

Now we will take a look at overload resolution with RValues and LValues as parameter.

void f1(string& s){
    cout<<"void f1(string& s):"<<s<<endl;
}

void f1(string&& s){
    cout<<"void f1(string&& s):"<<s<<endl;
}

int main()

{
    string s = "Hello";
    string&& s1 = "Hello";
    f1(s);
    f1(s1);
    return 0;
}

The output of this program is:

void f1(string& s):Hello
void f1(string& s):Hello

However we expected that call to f1(s1) will resolve to the function void f1(string&& s). This is not the case because compiler treats a named Rvalue reference as an Lvalue.

void f1(string& s){
    cout<<"void f1(string& s):"<<s<<endl;
}

void f1(string&& s){
    cout<<"void f1(string&& s):"<<s<<endl;
}
int main()

{
    string s = "Hello";
    f1(s);
    f1("Hello");
    return 0;
}

The output of this program is:

void f1(string& s):Hello
void f1(string&& s):Hello

This is as expected because “Hello” is an unnamed Rvalue reference and the call f1(“Hello”) resolves to void f1(string&& s).

We can also cast a Lvalue reference to Rvalue as shown below:

void f1(string& s){
    cout<<"void f1(string& s):"<<s<<endl;
}

void f1(string&& s){
    cout<<"void f1(string&& s):"<<s<<endl;
}

int main()

{
    string s = "Hello";
    f1(s);
    f1(static_cast<string&&>(s));
    return 0;
}

The output of this program is:

void f1(string& s):Hello
void f1(string&& s):Hello

The Standard Library provides a function std::move to obtain an Rvalue reference from a type which can be used instead of casting:

 
f1(std::move(s));

With this basic idea of RValue references we will move into forwarding & move semantics of C++11 in the next posts.

Advertisements
Comments
  1. […] the last post we discussed about RValue references in C++11.The next logical step will be to move forward to […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s