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.

¿Fue útil?

Solución

Las funciones de la plantilla

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;
}

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top