2015-03-10 2 views
1

- это отсутствие «частичной специализации шаблонов» для функций, фактически являющихся недостатками? Когда я определяю шаблон, а также перегрузку, чтобы действовать как специализация, он всегда работает.Частичная специализация шаблонов может не работать для функций, но не перегружает одну и ту же вещь?

template<typename T> 
static T Func(T a) { std::cout << "a"; return a; } 
static long Func(long a) { std::cout << "b"; return a; } 

Как и в это не противоречит Func<long> с точки зрения логического вывода. то есть Func(22l); вызывает правильную функцию и без двусмысленности.

Разве это не так хорошо, как шаблонная специализация для функций? Есть ли подводные камни с раскрытием таких функций, на которые я должен следить?

Редактировать: Я вижу одно отличие: Func<long> не может вызвать перегрузку, поэтому здесь НЕОБХОДИМО ЗАПРЕЩАЕТСЯ ТРЕБУЕТСЯ ... определенно один из потенциальных источников замешательства, особенно если ссылаться на него из другого шаблона.

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

template<typename T, typename U> 
static U Func(T a, U b) { std::cout << "a"; return a; } 
template<typename T> 
static long Func(T a, long b) { std::cout << "b"; return a; } 

Func<long>(12, 22); // invokes template 
Func<long>(12, 22l); // invokes "specialization" 
+1

Я не уверен, что это подходящий пример. Разве вторая функция не должна быть шаблоном? Хотя с меньшим количеством параметров? т. е. текущий пример более сродни * полной * специализации, чем к * частичной * специализации. –

+0

Спасибо, я обновил с лучшим примером. Кажется, что это работает в простом случае, хотя это открывает двери для многих возможностей, о которых я, возможно, еще не думал ... – VoidStar

ответ

2

Рассмотрим

template<class R, class T> 
R convert(const T&); 

Предположим, что мы хотим сделать что-то особенное для convert<void>(/*something*/) (то есть, в случае, когда R является void). Вы не можете сделать это с простой перегрузкой или полной специализацией. (Обычным трюком является делегирование статической функции-члена шаблона вспомогательного класса, который может быть частично специализированным.)

+0

На самом деле это похоже на то, что это работает для меня (VS2013). 'шаблон <класс R, класс T> R convert (const T & a) {std :: cout <<" a "; } template R convert (const long & a) {std :: cout << "b"; } ', а затем' convert (12) 'и' convert (12l) 'call a и b соответственно. РЕДАКТ: неважно, я думаю, вы имели в виду поворот на пустоте. – VoidStar

+0

Да, я согласен, мы ограничены выводом, поэтому мы не можем специализироваться на возврате с использованием перегрузки. – VoidStar

+0

Я думаю, что могу написать две перегрузки 'convert', которые делают то, что вы хотите через SFINAE. Конечно, это использование отбойного молотка, чтобы убить муравей, но если ему нужно убить ... – Yakk

 Смежные вопросы

  • Нет связанных вопросов^_^