While playing with universal references, I came across this instance where clang and gcc disagree on overload resolution.
#include <iostream>
struct foo {};
template<typename T>
void bar(T&) { std::cout << "void bar(T&)\n"; }
template<typename T>
void bar(T&&) { std::cout << "void bar(T&&)\n"; }
int main()
{
foo f;
bar(f); // ambiguous on gcc, ok on clang
}
gcc reports the call above is ambiguous. However, clang selects the T&
overload and compiles successfully.
Which compiler is wrong, and why?
Edit:
Tested the same code on VS2013 Preview, and it agrees with clang; except Intellisense, which is on gcc's side :-)
“l-value” refers to a memory location that identifies an object. “r-value” refers to the data value that is stored at some address in memory. References in C++ are nothing but the alternative to the already existing variable. They are declared using the '&' before the name of the variable.
By overloading a function to take a const lvalue reference or an rvalue reference, you can write code that distinguishes between non-modifiable objects (lvalues) and modifiable temporary values (rvalues). You can pass an object to a function that takes an rvalue reference unless the object is marked as const .
An lvalue reference is formed by placing an & after some type. An rvalue reference is formed by placing an && after some type. An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.
Universal reference was a term Scott Meyers coined to describe the concept of taking an rvalue reference to a cv-unqualified template parameter, which can then be deduced as either a value or an lvalue reference.
The "universal reference" deduces the parameter to foo&
. The first template also deduces the parameter to foo&
.
C++ has a partial ordering rule for function templates that makes T&
be more specialized than T&&
. Hence the first template must be chosen in your example code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With