Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding lvalue to rvalue reference -- g++ bug?

As an answer to another question I wanted to post the following code (that is, I wanted to post code based on this idea):

#include <iostream>
#include <utility>      // std::is_same, std::enable_if
using namespace std;

template< class Type >
struct Boxed
{
    Type value;

    template< class Arg >
    Boxed(
        Arg const& v,
        typename enable_if< is_same< Type, Arg >::value, Arg >::type* = 0
        )
        : value( v )
    {
        wcout << "Generic!" << endl;
    }

    Boxed( Type&& v ): value( move( v ) )
    {
        wcout << "Rvalue!" << endl;
    }
};

void function( Boxed< int > v ) {}

int main()
{
    int i = 5;
    function( i );  //<- this is acceptable

    char c = 'a';
    function( c );  //<- I would NOT like this to compile
}

However, while MSVC 11.0 chokes at the last call, as it IHMO should, MinGW g++ 4.7.1 just accepts it, and invokes the constructor with rvalue reference formal argument.

It looks to me as if an lvalue is bound to an rvalue reference. A glib answer could be that the lvalue is converted to rvalue. But the question is, is this a compiler bug, and if it’s not, how does the Holy Standard permit this?


EDIT: I managed to reduce it all to the following pretty short example:

void foo( double&& ) {}

int main()
{
    char ch = '!';
    foo( ch );
}

Fails to compile with MSVC 11.0, does compile with MinGW 4.7.1, which is right?

like image 615
Cheers and hth. - Alf Avatar asked Oct 14 '12 10:10

Cheers and hth. - Alf


1 Answers

I haven't check the spec but I guess char can be automatically cast to int. Since you cannot assign anything (it's r-value) the R-value to temporary variable of type int (to be more explicit to (int)c value) will be passed.

like image 102
Maciej Piechotka Avatar answered Sep 22 '22 10:09

Maciej Piechotka