Шаблон специализированной функции для ссылочных типов - PullRequest
12 голосов
/ 13 января 2011

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

#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&

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

Ответы [ 3 ]

9 голосов
/ 13 января 2011

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

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

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

1 голос
/ 13 января 2011

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

0 голосов
/ 13 января 2011

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

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 ;} 
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...