Я смотрю на каком-Си ++ коде и не понимаю цели декларации шаблона в этой ситуации:путаться с шаблоном C++
template<> void operator>>(const ClassA& s, const ClassB d) {...}
Что семантика template<>
?
Я смотрю на каком-Си ++ коде и не понимаю цели декларации шаблона в этой ситуации:путаться с шаблоном C++
template<> void operator>>(const ClassA& s, const ClassB d) {...}
Что семантика template<>
?
Это, действительно, специализированная специализация, как и другие, упомянутые ранее. Должен быть некоторый ранее объявленный шаблон функции, такой как:
template<typename T, typename U>
void operator>>(const T& s, const U d) {...}
Однако, это довольно ошибочно. Гораздо лучше удалить template<>
, так что operator>>
просто перегрузится. Проблема специализации шаблона заключается в том, что это может привести к неожиданному поведению при наличии перегруженных функций (и operator>>
имеет много перегрузок), поскольку специализация не перегружает. Это означает, что компилятор сначала выбирает наиболее подходящую перегрузку для функции, а затем, если выбранная перегрузка является шаблоном функции, она ищет специализированные специализации, чтобы увидеть, есть ли соответствующий.
Классический пример (к сожалению, я не помню, где я его читал). Рассмотрим этот перегруженный шаблон функции:
template <typename T>
void Function(T param);
template <typename T>
void Function(T* param);
template <>
void Function(int* param);
main()
{
int i = 5;
Function(&i);
}
Как и ожидалось, специализация шаблона для int*
называется. Но просто изменить порядок определений функций:
template <typename T>
void Function(T param);
template <>
void Function(int* param);
template <typename T>
void Function(T* param);
main()
{
int i = 5;
Function(&i);
}
Теперь общий шаблон для T*
называется, так как мы специализируемся шаблон для T
, а не для T*
, и этот второй шаблон лучше подходит для нашего звонка. Это можно было бы избежать, если бы мы перегрузили функцию вместо специализировать шаблон:
void Function(int* param);
Теперь порядок декларирования не имеет значения, мы всегда будем называть перегрузки для int*
.
ОБНОВЛЕНИЕ: Теперь я знаю, кому кредит. Я читал об этом в article Херб Саттер. Пример был предоставлен Питером Димовым и Дейвом Абрахамом.
Это template specialization: (полностью или частично) разрешение шаблона для определенного типа. (Ваш конкретный пример, как представляется, полная специализация, так как нет больше параметров шаблона не остается нерешенной в нем. Если шаблон имеет несколько параметров, и вы специализируетесь только некоторые из них, это называется частичный шаблон специализации)
Это позволяет обеспечить оптимизацию типа, специфичный для данного шаблона или сделать много хитрых трюков, такими как обнаружение статического типа переменных и т.д.
éter Я не думаю, что пример, представленный OP, действителен. Если я правильно помню, вы не можете специализировать функцию, вам нужно ее перегрузить. Специализация работает только для классов. – greatwolf
@Victor, функции шаблона имеют некоторые ограничения по сравнению с шаблонами классов; dunno, как (и есть ли) это изменило C++ 03 и позже, хотя. Тем не менее, связанные примеры в C++ FAQ, похоже, являются специализированными функциями шаблонов, поэтому я полагаю, что он должен работать :-) –
éter hmm interesting, я просто попробовал его на нескольких компиляторах и действительно принимает код. Похоже, что частичная специализация не работает на функции. Должно быть, это то, о чем я думал. – greatwolf
вы можете использовать этот синтаксис, если вы хотите, чтобы обеспечить a специальный обработчик для конкретной templa te type. Рассмотрим:
// A normal template definition.
template <typename AType>
whoami() { std::cout << "I am an unknown type."; }
// Now we specialize.
template <>
whoami<int>() { std::cout << "I am an integer!"; }
Там какая-то другая ерунда участвуют, в частности, «частичная специализация», но это основная функция template <>
.
Спасибо за ответ, так что это еще один трюк, который усложняет язык. Подобно перегрузке, я не думаю, что это хорошая идея: http://gbracha.blogspot.com/2009/09/systemic-overload.html – mathk
@mathk: Я не согласен с большинством идей в статье, которую вы связываете. – Gorpik
Вы не согласны с одним из тех парней, которые разрабатывают Java. Что тебе не нравится? – mathk