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 :-)
The "universal reference" deduces the parameter to
foo&
. The first template also deduces the parameter tofoo&
.C++ has a partial ordering rule for function templates that makes
T&
be more specialized thanT&&
. Hence the first template must be chosen in your example code.