1

I'm going through r-value references and move semantics, currently, and I'm seeing an odd discrepancy in my own coding experimentation.

Given the below code:

#include <iostream>

using namespace std;

class X{};

void g(X&& t) // A
{
    cout << "Rref call" << endl;
}    

void g(X& t) // B
{
    cout << "Lref call" << endl;
}    

template<typename T>
void f(T&& t)
{
    g(forward<T>(t));
}

int main()
{
    X x;
    f(x);   // 1
    f(X()); // 2

    return 0;
}

Will generate the expected output here:

Lref call

Rref call

However, if I go ahead and delete the overloaded function g that takes an r-value reference (denoted above on comment line // A), I get the following output:

Lref call

Lref call

How does this work out? Why doesn't the compiler complain about a call to g(X& t) while trying to pass in a X&&?

Community
  • 1
  • 1
Joefers
  • 97
  • 7
  • 3
    Are you using Visual Studio? If so, it has a [non-standard extension](http://stackoverflow.com/questions/1565600/how-come-a-non-const-reference-cannot-bind-to-a-temporary-object) to allow temporaries to bind to non-const references. It fails [in this example](http://ideone.com/TcJbJA). – James Adkison Apr 15 '16 at 18:14
  • James, that looks to be exactly it. Was going nuts trying to figure out the logic happening. Much obliged. – Joefers Apr 15 '16 at 18:20

1 Answers1

3

When you comment out the g(X&& t) overload, you're using an MSVC extension that allows binding rvalues to non-const lvalue references. If you turn up the warning level to /W4, MSVC will tell you a non-standard extension is being used.

Both gcc and clang fail to compile the code with that overload commented out.

Community
  • 1
  • 1
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Yup! Was using Visual Studio and it was happily accepting this. Thanks kindly. – Joefers Apr 15 '16 at 18:27
  • This is one of the most terrible bugs in MSVC. And while it might had some sense back in the days when there were no rvalue references, it has 0 sense now. They should've turned it off for C++11 code. – SergeyA Apr 15 '16 at 18:45
  • @SergeyA Well it is turned off if you compile with `/W4` and `/WX`, as you should be :) But I don't want to make excuses for them, this is a terrible extension. – Praetorian Apr 15 '16 at 21:39