Especialización de plantillas C ++ basada en el valor del tiempo de compilación
-
12-12-2019 - |
Pregunta
Estoy sintiendo mi camino en la meta-programación de plantillas, lentamente y no estoy seguro de cómo implementar lo siguiente:
// hpp file
enum MyEnum { Alive = 0, Dead };
class A {
public:
template<typename T, typename O, MyEnum ls>
static int Register();
};
// elsewhere in the code...
A::Register<IType1, Type1, Dead>();
En el tiempo de compilación, sabré qué valor enum cuenta es el tercer tipo de plantilla (invariante de tiempo de compilación), ya sea muerto o vivo.¿Es posible definir dos cuerpos para la función de registro, algo así como:
// desired hpp file
template<typename T, typename O, Alive>
int Register();
template<typename T, typename O, Dead>
int Register();
// corresponding desired .inc file
template<typename T, typename O, Alive>
int Register() { // Alive specific implementation ... }
template<typename T, typename O, Dead>
int Register() { // Dead specific implementation ... }
He echado un vistazo a: Especialización de plantillas C ++ con valor constante
Pero no he podido averiguar cómo hacerlo aplicarse a esta situación.
Solución
no pueden ser parcializadas.La solución es envolverla en una estructura:
template<typename T, typename O, MyEnum ls>
struct foo;
template<typename T, typename O>
struct foo <T, O, Alive> {
static int Register() {
// ...
}
};
template<typename T, typename O>
struct foo <T, O, Dead> {
static int Register() {
// ...
}
};
template<typename T, typename O, MyEnum ls>
int Register() {
return foo<T, O, ls>::Register();
}
Otros consejos
muy tarde a la fiesta aquí, pero.
Una forma de hacer esto que creo que es conceptualmente más simple y también más fácil de leer es simplemente hacer los diferentes valores de su enumer diferentes tipos (dentro de un espacio de nombres, para mantenerlo limpio), y tomarloVentaja de la sobrecarga de funciones (plantilla):
namespace State {
struct Dead {};
struct Alive {};
}
template<typename T, typename O>
int Register(State::Dead) {
return 1;
}
template<typename T, typename O>
int Register(State::Alive) {
return 2;
}
Llámenos así:
int main() {
Register<int,int>(State::Dead());
Register<int,int>(State::Alive());
return 0;
}