Предположим, что я хочу написать общую функцию void f<T>()
, которая делает одно, если T
- тип POD, а другая вещь, если T
- не-POD (или любой другой произвольный предикат).
Одним из способов достижения этой цели будет использование шаблона отправки тегов, например стандартная библиотека, с категориями итератора:
template <bool> struct podness {};
typedef podness<true> pod_tag;
typedef podness<false> non_pod_tag;
template <typename T> void f2(T, pod_tag) { /* POD */ }
template <typename T> void f2(T, non_pod_tag) { /* non-POD */ }
template <typename T>
void f(T x)
{
// Dispatch to f2 based on tag.
f2(x, podness<std::is_pod<T>::value>());
}
Альтернативой может быть использование статической функции-члена частично специализированных типов:
template <typename T, bool> struct f2;
template <typename T>
struct f2<T, true> { static void f(T) { /* POD */ } };
template <typename T>
struct f2<T, false> { static void f(T) { /* non-POD */ } };
template <typename T>
void f(T x)
{
// Select the correct partially specialised type.
f2<T, std::is_pod<T>::value>::f(x);
}
Каковы плюсы и минусы использования одного метода над другим? Что бы вы порекомендовали?