Does an lvalue argument prefer an lvalue reference parameter over a universal reference?
Asked Answered
T

1

17

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 :-)

Triciatrick answered 31/7, 2013 at 19:31 Comment(2)
This is GCC bug 54425.Stinson
Both intel(13.0.1) and pgi(13.4) compilers also yield an error about that.Tutor
I
18

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.

Indispensable answered 31/7, 2013 at 19:34 Comment(1)
Found the standard reference - from N3691 section §14.8.2.4/9Triciatrick

© 2022 - 2024 — McMap. All rights reserved.