Предпочитает ли аргумент 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&&, Следовательно, первый шаблон должен быть выбран в вашем примере кода.

Другие вопросы по тегам