Supponiamo di voler scrivere una funzione generica void f<T>()
, che fa una cosa se T
è un tipo POD e un'altra cosa se T
non è POD (o qualsiasi altro predicato arbitrario).Invio di tag rispetto a metodi statici su classi parzialmente specializzate
Un modo per raggiungere questo obiettivo sarebbe quello di utilizzare un modello di tag-spedizione come la libreria standard fa con le categorie di iteratori:
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>());
}
Un'alternativa sarebbe quella di utilizzare la funzione di membro static di tipi parzialmente specializzati:
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);
}
Quali sono i pro e i contro dell'utilizzo di un metodo rispetto all'altro? Quale raccomanderesti?
Qualunque cosa faccia galleggiare la vostra barca. Trovo la seconda versione più "typetraity" e accattivante, perché c'è meno codice ausiliario e meno concetti nascosti. Inoltre aggiungerei l'inoltro per l'argomento! –