Подтвердить что ты не робот

Параметр lvalue предпочитает опорный параметр lvalue по универсальной ссылке?

Во время игры с универсальными ссылками я столкнулся с этим экземпляром, где clang и gcc не согласны с разрешением перегрузки.

#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 вызов выше неоднозначен. Однако clang выбирает T& перегрузку и компиляции успешно.

Какой компилятор ошибочен и почему?

Изменить:
Протестировал тот же код в VS2013 Preview, и он согласен с clang; кроме Intellisense, который находится на стороне gcc: -)

4b9b3361

Ответ 1

"Универсальная ссылка" выводит параметр foo&. Первый шаблон также выводит параметр foo&.

С++ имеет правило частичного упорядочения для шаблонов функций, которое делает T& более специализированным, чем T&&. Следовательно, первый шаблон должен быть выбран в вашем примере кода.