Предпочитает ли аргумент 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 сообщает, что вызов выше неоднозначен. Тем не менее, Clang выбирает T&
перегрузка и успешно компилируется.
Какой компилятор не так и почему?
Редактировать:
Протестировал тот же код на VS2013 Preview, и он согласен с clang; кроме Intellisense, который находится на стороне gcc:-)
1 ответ
Решение
"Универсальная ссылка" выводит параметр в foo&
, Первый шаблон также выводит параметр в foo&
,
C++ имеет правило частичного упорядочения для шаблонов функций, которое делает T&
быть более специализированным, чем T&&
, Следовательно, первый шаблон должен быть выбран в вашем примере кода.