Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding r-value to l-value reference is non-standard Microsoft C++ extension

I've been working on a project recently, and I decided to install ReSharper C++ to Visual Studio. When it analysed my code it spat out a bunch of new warnings (apparently I have bad coding habits..). One of them that took me a while to figure out was Binding r-value to l-value reference is non-standard Microsoft C++ extension. I've recreated the warning with the following code:

Type foo(Type t1, Type t2) {
    return Type(t1.value & t2.value);
}

The expression t1.value & t2.value triggers the warning. I understand the second part of the warning, which means that my code only compiles due to a Microsoft extension, and other compilers would refuse to compile it. I'm using an overloaded operator, which returns an object (called Datum) which Type takes as a constructor parameter, as a reference (Type::Type(Datum& dat)).

With some playing around, I managed to make the warning go away by refactoring the code:

Type bar(Type t1, Type t2) {
    Datum datum = t1.value & t2.value;
    return Type(datum);
}

To my understanding, this is functionally equivalent to the code that generated the warning. What I'd really like to know is whether there's something here that I should be aware of, because I'm pretty confused about why one function complains and one doesn't.

I think I've got it figured out. I already had the question typed out, so I'm going to post it with what I found, for the reference of others. I don't really have enough knowledge to go into detail, so please feel free to expand on or correct my answer if it isn't satisfactory :)

like image 524
brads3290 Avatar asked Apr 18 '15 13:04

brads3290


1 Answers

That's one way to remove the warning: the variable is an lvalue, so can bind directly to the dodgy constructor's reference parameter, while the expression result is an rvalue which can't.

A better solution is to fix the constructor to take its argument by value or constant reference:

Type(Datum dat)         // value
Type(Datum const & dat) // constant reference

Now you can give the argument as either an lvalue or an rvalue.

like image 162
Mike Seymour Avatar answered Oct 18 '22 13:10

Mike Seymour