2012-04-04 12 views
5

Dada una plantillaplantilla especializan en base a la positividad del argumento

template <int n> 
void f(){...}; 

Sé que puedo especializar que para valores específicos de n haciendo:

template <> 
void f<2>(){...}; 

Pero, ¿existe un método que me permite para especializarlo en positivo n?

se me ocurrió hacer lo siguiente

template <int n> 
void f<n>(){ 
    int dummy[n]; //invalid for n < 0 
    ... 
}; 

Así que para n<0 este código es válido y el compilador podría recurrir a la definición anterior. Lamentablemente, todo lo que obtengo es un error redefinition of 'void f<n>()'.

Nota: Supongo que probablemente no sea compatible con la norma. Estoy preguntando si no hay algún método (tal vez alguna metaprogramación de plantillas) para lograr este efecto.

Respuesta

13

Una opción sería usar otro nivel de indirección. Defina una plantilla auxiliar que acepte dos argumentos: el número n y un bool que representa si n es negativo, luego especialice esa plantilla para cuando n sea negativo. Luego, haga que su función f cree una instancia de la plantilla con los argumentos correctos.

Por ejemplo:

template <int n, bool isNegative> struct fImpl { 
    static void f() { 
     /* ... code for when n is positive ... */ 
    } 
}; 
template <int n> struct fImpl<n, true> { 
    static void f() { 
     /* ... code for when n is negative ... */ 
    } 
}; 

template <int n> void f() { 
    fImpl<n, (n < 0)>::f(); 
} 

Otra opción es utilizar SFINAE overloading y la clase std::enable_if plantilla de C++ 11 (o equivalente de Boost);

template <int n> void f(typename std::enable_if<(n < 0)>::type* = 0) { 
    /* ... n is negative ... */ 
} 

template <int n> void f(typename std::enable_if<(n >= 0)>::type* = 0) { 
    /* ... n is positive ... */ 
} 

Cada una de estas funciones sólo estarán disponibles para la resolución de sobrecarga si n tiene el signo correcto, por lo que la versión correcta siempre será llamado.

Espero que esto ayude!

+5

Materia de estilo, pero prefiero poner 'enable_if' en el tipo de devolución para que no haya un parámetro mágico que cuelgue confundiendo cosas (usuarios y el tipo de función). – GManNickG

Cuestiones relacionadas