2010-08-14 9 views
15

¿hay alguna restricción/problema al utilizar una enum como argumento de plantilla (tipo) en C++?Usando enum como argumento de tipo de plantilla en C++

Ejemplo:

enum MyEnum 
{ 
    A, B, C, D, E 
}; 

template <typename _t> 
class MyTemplate 
{ 
public: 
    _t value; 

    void func(const _t& param) { /* .... */ } 
}; 

// .... 

MyTemplate<MyEnum> MyInstance; 

Mi problema real utilizando MSVC++ a través de VS 2008 (SP1) en Win32/x86 son varios errores de compilación (= errores reportados por el compilador) en asociación con las clases de uso de enumeraciones como argumentos de la plantilla. Como desafortunadamente mi proyecto se ha vuelto un poco complejo (puede considerarlo como un error de diseño: P), las clases de plantilla que generan estos errores se derivan, anidan e incluso se especializan en una clase con parámetro de plantilla enum.

Al tratar de compilar, el compilador informa de muchos errores incorrectos/inútiles como "C2059: error de sintaxis: 'public'" en las líneas donde solo hay un comentario. Muchos de ellos podría solucionar reemplazando en métodos similares al del ejemplo const _t & param por _t (es decir, copiando el parámetro), pero tampoco podría corregir todos estos errores ni tengo una pista de por qué esto "ayuda ". ** Lo sé, el ejemplo simple anterior compila sin errores.

Usando int en lugar de enum, mi proyecto compila sin errores.

¡Gracias de antemano por cualquier pista o sugerencia!


Editar:

Después de todo, en serio considerar esto como un error del compilador. Cuando traté de reproducir los errores con código simplificado, los obtuve solo en el 50% de todas las "compilaciones", no muy deterministas:
P. ej. intentado compilar, e informó estos errores. Reconstruir - sin cambios. Se eliminó un comentario, compilación, sin cambios. Reconstruir - y luego: sin errores, compila bien.

Ya conocí algunos errores del compilador (2 o 3 supongo que dentro de 20k líneas de código), pero este me parece muy extraño.
¿Alguna sugerencia de cómo averiguar si es es el compilador?

+3

"Al tratar de compilar, el compilador informa muchos errores incorrectos/inútiles" Esos errores "inútiles" a menudo tienen una descripción muy detallada de qué/y dónde salió mal. Simplemente lea la salida del compilador en lugar de "lista de errores". – SigTerm

+0

Gracias por la pista, pero lo hice. Siempre lo hago ^^ Pero no me ayudó ... Errores: error C2059: error de sintaxis: error 'público' C2143: error de sintaxis: falta '>' antes ';' error C2143: error de sintaxis: falta ';' antes de '}' error fatal C1004: fin de archivo inesperado encontrado (y luego algunos otros errores, no relacionados con esta pregunta) todos estos solo aparecen cuando se usa la enumeración y desaparecen cuando se usa int – dyp

+0

Esto se ve perfectamente bien para mí . Esto es un error del compilador o tu error, y si vas a adivinar, la apuesta del 99.9% es que eres tú. Pero no hay nada de malo en los fragmentos que has publicado. Publique una pequeña muestra completa dentro de sí misma y los errores exactos del compilador que crea. – Omnifarious

Respuesta

4

En referencia a la pregunta original:

are there any restrictions/problems using an enum as template (type) argument in C++?

No se encontró ninguna - y no creo que los hay. Puede ser una mala idea porque esta técnica no se usa con tanta frecuencia, por lo que podría haber algunos (más) errores de compilación relacionados con esto, tal como lo dijo Potatoswatter.
Consideremos el siguiente ejemplo:

enum MyEnum : int 
{ 
    A, B, C, D 
}; 

template <typename _t> class MyTemplate 
{ 
public: 
    void print() 
    { 
     cout << "not using any specialisation" << endl; 
    } 
}; 
    template <> class MyTemplate <MyEnum> 
    { 
    public: 
     void print() 
     { 
      cout << "MyEnum specialisation" << endl; 
     } 
    }; 
    template<> class MyTemplate <int> 
    { 
    public: 
     void print() 
     { 
      cout << "int specialisation" << endl; 
     } 
    }; 

template <typename _t> void print(_t param) 
{ 
    MyTemplate<_t> m; 
    m.print(); 
} 


int main() 
{ 
    print(A); 
    print(5); 

    return 0; 
} 

La salida es:

MyEnum specialisation
int specialisation

Para estos ejemplos simples, todo funciona bien y como era de esperar y la enumeración funciona perfectamente como cualquier otro tipo que tipo de plantilla argumento (= No veo ningún motivo para los problemas).

Originalmente, presenté el ejemplo en la pregunta para mostrar lo que quería decir con esa pregunta (enum como argumento de tipo de plantilla, mostrar usos posibles como tipo de argumento de miembro o método, etc.). Para proporcionar un poco de información de fondo, es decir, , por qué hice esa pregunta (imagino que pregunté "¿hay algún problema con int?), Mencioné estos problemas extraños al compilar mi proyecto real.
Lo siento, no pude extraer un fragmento de él que sea completo en sí mismo y reproducir los errores, lo mínimo que pude obtener fueron 2k líneas de código divididas en 4 archivos, donde un "error de sintaxis: 'público'" y algunos otros errores de sintaxis surgieron cuando compilé el proyecto, y aparecieron/desaparecieron bajo ciertas circunstancias, al eliminar un comentario o reconstruir (= eliminar los archivos intermedios). Desafortunadamente, la reconstrucción no ayuda con el proyecto original, donde tuve que reemplazar una especialización de un tipo enum a int.

Así que, gracias a todos por sus consejos y sugerencias. El problema subyacente me parece que es un error del compilador, lo que hace que la pregunta sea un poco inútil, ya que la respuesta parece ser solo "no, no hay restricciones usando una enumeración como argumento de tipo de plantilla". Lo siento por los inconvenientes ocasionados.

0

MSVC maneja los parámetros de la plantilla enum (valor) de forma extraña. Las entradas se promocionan a int de forma incorrecta a veces y los operadores no se definen correctamente. Parece que en realidad no prueban el motor de plantillas con los tipos enum.

Demostrar que es un error de compilación es simple: poner código válido y observar si se compila con éxito. Su ejemplo es obviamente compatible, por lo que el problema (o el error, de todos modos) es de ellos.

Editar: en una inspección más cercana que decir que el ejemplo hace no reproducir el error. Ni nosotros ni nadie más podemos ayudarlo hasta que produzca un ejemplo que sí lo haga.

+0

Se puede probar que un compilador tiene una falla solo de dos maneras: a) validar según las Normas relevantes b) Leer la documentación y verificar si es un problema/defecto conocido – Chubsdad

+0

El OP no es t suministrando un valor enum * * como parámetro de la plantilla, sin embargo, el enum * tipo * es el parámetro. –

7

Sí, hay restricciones. Por ejemplo, no se puede utilizar una enumeración anónima como un argumento de plantilla de acuerdo con C++ 03 14.3.1[temp.arg.type]/2

A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter.

Así que el código siguiente no es válida en C++ 03:

template <typename T> 
void f(T) {} 

enum {A}; 

int main() { 
    f(A); 
} 

Es válido en C++ 11 sin embargo.

Cuestiones relacionadas