Breaking Change for RValue References in Visual Studio 2010 RC

The Release Candidate of Visual Studio 2010 has changed the behaviour of RValue references slightly compared to the implementation in the Visual Studio 2010 beta versions. This is because the C++0x standard commitee has changed the RValue reference feature a bit and Visual Studio 2010 RC has incorporated those standard changes. Unfortunately, this might lead to compiler errors when you try to build code that is following the old standard. Let me give an example. Previously using a beta version of Visual Studio 2010 that was using the old C++0x standard, the following code would compile without any problems.

#include <iostream>
using namespace std;
// Increment value by 1 using RValue reference parameter.
int increment(int&& value)
{
   cout << "value = " << value << endl;
   value++;
   return value;
}
int main()
{
   int a = 10;
   int b = 20;
   // Increment a
   int result = increment(a);
   cout << "  a=" << a << ", b=" << b << ", result=" << result << endl;
   // Increment b
   result = increment(b);
   cout << "  a=" << a << ", b=" << b << ", result=" << result << endl;
   // Increment an expression
   result = increment(a + b);
   cout << "  a=" << a << ", b=" << b << ", result=" << result << endl;
   // Increment a literal
   result = increment(3);
   cout << "  a=" << a << ", b=" << b << ", result=" << result << endl;
   return 0;
} 

However, when trying to compile this using the latest release candidate of Visual Studio 2010, you will get the following errors:

rvalue_test.cpp(18): error C2664: 'increment' : cannot convert parameter 1 from 'int' to 'int &&'
          You cannot bind an lvalue to an rvalue reference
rvalue_test.cpp(21): error C2664: 'increment' : cannot convert parameter 1 from 'int' to 'int &&'
          You cannot bind an lvalue to an rvalue reference

These are related to the lines that are trying to increment a and b. Incrementing an expression or a literal still works as before. To get rid of those errors, you need to convert the lvalue to an rvalue. You can use the std::move function for this as shown in red below.

#include <iostream>
using namespace std;
// Increment value by 1 using RValue reference parameter.
int increment(int&& value)
{
   cout << "value = " << value << endl;
   value++;
   return value;
}
int main()
{
   int a = 10;
   int b = 20;
   // Increment a
   int result = increment(std::move(a));
   cout << "  a=" << a << ", b=" << b << ", result=" << result << endl;
   // Increment b
   result = increment(std::move(b));
   cout << "  a=" << a << ", b=" << b << ", result=" << result << endl;
   // Increment an expression
   result = increment(a + b);
   cout << "  a=" << a << ", b=" << b << ", result=" << result << endl;
   // Increment a literal
   result = increment(3);
   cout << "  a=" << a << ", b=" << b << ", result=" << result << endl;
   return 0;
}

This now compiles without any errors and produces the following output:

value = 10
  a=11, b=20, result=11
value = 20
  a=11, b=21, result=21
value = 32
  a=11, b=21, result=33
value = 3
  a=11, b=21, result=4

Now, it again works as expected :)

Share

Leave a Comment

Name: (Required)

E-mail: (Required)

Website:

Comment: