2009-08-21 12 views
5

Tengo problemas para compilar este código en Linux, pero funciona perfectamente en Windows.Problema de plantilla de C++ en el código multiplataforma

de Windows compilador: Visual Studio 2005

Linux compilador: gcc versión 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)

class DoSomething 
{ 
    public: 
    template <class DataType> 
    bool Execute() 
    { 
     //do something here 
    } 
}; 


template <class Operator> 
TypeSwitch(int DataTypeCode, Operator& Op) 
{ 
    switch (DataTypeCode) 
    { 
    case 1: return Op.Execute<char>(); 
    case 2: return Op.Execute<int>(); 
    //snip; 
    } 
} 

//To call the operator 
TypeSwitch(Code,DoSomething); 

En Windows este código funciona perfectamente y hace exactamente lo que quiero que haga En Linux, consigo los errores:

de error: se esperaba primaria-expresión antes '>' símbolo

de error: se esperaba primaria-expresión antes ')' símbolo

para cada una de las líneas con el caso declaración.

¿Alguna idea?

Gracias, Mike

+0

líneas Wich están señalados por los errores? – Klaim

+0

Él dice en su publicación: "para cada una de las líneas con la declaración del caso". – DeusAduro

+0

¿Seguro que compila el código? puedo ver varios errores ¿Dónde está el tipo de devolución TypeSwitch? –

Respuesta

13

El problema es que cuando el compilador encuentra Op.Execute<char>(); y trata de analizarlo, se confunde.

Op es un nombre dependiente, por lo que el compilador no sabe mucho acerca de sus miembros. Por lo tanto, no sabe que Execute es una función de plantilla. En cambio, asume que el < significa menos que. que está tratando de comparar algún miembro desconocido Execute con otra cosa.

Así que en vez, la línea debe tener este aspecto:

case 1: return Op.template Execute<char>(); 

Ahora el compilador sabe que Execute es una plantilla, así que cuando encuentra < no es "menor que", sino el comienzo de la plantilla parámetros.

El problema es similar a cómo necesita typename al especificar tipos que pertenecen a un nombre dependiente. Cuando se refiere a una función de miembro de plantilla, y los argumentos de la plantilla se proporcionan explícitamente, necesita la palabra clave template.

El comportamiento de GCC es correcto y MSVC es demasiado indulgente. Si se agrega la palabra clave template, el código funciona en ambos compiladores (y sea correcta de acuerdo con el estándar)

+2

¡Bienvenido al mundo maravilloso y mágico de las reglas de análisis de plantillas de C++! –

+0

¡Ah, gracias! Lo intentaré cuando regrese al trabajo el lunes por la mañana, pero tu descripción parece correcta. ¡Me encantan las sutilezas con las plantillas! – miked

+0

Solo un seguimiento para cualquier otra persona que necesite esto: lo intenté y descubrí que hay un error conocido en MSVC de que la solución anterior no funciona. Entonces en Windows necesita Op.Execute () y en no-ventanas necesita Op.template Execute (). – miked

1
case 1: return Op.template Execute<char>(); 
case 2: return Op.template Execute<int>(); 

Ver: template as qualifier

Además, TypeSwitch() devuelve un bool

Cuestiones relacionadas