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

Специализированный шаблон функции для ссылочных типов

Почему вывод этого кода:

#include <iostream>  
template<typename T> void f(T param) 
{ 
   std::cout << "General" << std::endl ; 
} 
template<> void f(int& param) 
{ 
   std::cout << "int&" << std::endl ; 
}  

int main() 
{   
  float x ;  f (x) ;   
  int y ; f (y) ;   
  int& z = y ; f (z) ; 
}  

является

Общие
Общие
Общие

Третий сюрприз, потому что функция была специально предназначена для int&

Изменить: я знаю, что перегрузка может быть правильным решением. Я просто хочу изучить логику этого.

4b9b3361

Ответ 1

Тип выражения y и выражение z равно int. Ссылка, отображаемая в выражении, не будет содержать ссылочный тип. Вместо этого тип выражения будет ссылочным типом, при этом выражение будет lvalue.

Итак, в обоих случаях T выводится на int, и поэтому явная специализация вообще не используется.

Что важно отметить (кроме того, что вы действительно должны использовать перегрузку, как сказал еще один парень), заключается в том, что у вас есть параметр функции без ссылки в вашем шаблоне. Прежде чем сделать вывод T в отношении типа аргумента, тип аргумента будет преобразован из массивов в указатель на их первый элемент (для функций, аргументы будут преобразованы в указатели на функции). Таким образом, шаблон функции с необязательным параметром функции не позволяет точно вычитать.

Ответ 2

Ссылка - это просто псевдоним, а не тип. Поэтому, когда вы вызываете f (z), он соответствует первой версии с T = int, что является лучшим вариантом, который T = int &. Если вы измените T на T &, то как int, так и int & аргументы вызовут вторую версию.

Ответ 3

Я знаю, что это не ответ, но, ИМХО, вы можете попробовать это, используя подобный подход в структуре:

template<typename T>
struct value_traits
{
    static void print(){std::cout << "General" << std::endl ;} 
};

template<>
struct value_traits<const long>
{
    static void print(){std::cout << "const long" << std::endl ;} 
};

template<>
struct value_traits<std::vector<unsigned char> >
{
    static void print(){std::cout << "std::vector<unsigned char>" << std::endl ; }
};

template<>
struct value_traits<const int>
{
       static void print(){std::cout << "const int" << std::endl ;} 
};