Почему не выбрана перегрузка при прямой ссылке для шаблонов функций?

#c #overloading #function-templates #forward-reference

#c #перегрузка #функции-шаблоны #прямая ссылка

Вопрос:

Фрагмент текста:

 #include <iostream>

template<typename T>
struct Printer{};

template<typename T>
void test(Tamp;amp;)
{
    std::cout << "Primary template calledn";
}

template<typename T>
void test(Printer<T>amp;amp;)
{
    std::cout << "Specialized template calledn";
}

int main()
{
    auto t = Printer<int>{};
    test(0);
    test(t);
}
 

Вот демонстрация

Почему печатается два раза Primary template called ?

Если удалить прямую ссылку из второго шаблона, то Printer выбирается перегрузка.

Почему он не выбран с amp;amp; помощью?

Комментарии:

1. amp;amp; не привязывается к значениям lvalues и t является значением lvalue . amp;amp; в вашем примере это не ссылка на пересылку, это просто ссылка на значение rvalue.

2. @Evg: Тогда почему он привязывается к первому шаблону?

3. Потому что in Tamp;amp; amp;amp; это ссылка на пересылку, а in Printer<T>amp;amp; amp;amp; это ссылка на значение rvalue . Единственный способ получить перенаправляющую ссылку — это написать Tamp;amp; . Even const Tamp;amp; больше не является ссылкой для пересылки.

4. Хорошо, я понял… тогда что такое Printer<Tamp;amp;>?

5. Printer с T заменой Tamp;amp; на . Здесь нет волшебства. Только Tamp;amp; волшебные.

Ответ №1:

Ссылка на пересылку работает только для Tamp;amp; , а не C<T>amp;amp; для nor const Tamp;amp; .

 test(0); // Call test(Tamp;amp;) with T=int
test(t); // Call test(Tamp;amp;) with T=Printer<int>amp;