Специализированный шаблон функции для ссылочных типов
Почему вывод этого кода:
#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&
Изменить: я знаю, что перегрузка может быть правильным решением. Я просто хочу изучить логику этого.
Ответы
Ответ 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 ;}
};