2011-02-09 7 views
68

No entiendo, me parece que la llamada a f es completamente inequívoca, pero no se puede compilar con expected primary-expression before ‘int’. Si hago un comentario en la línea con la llamada al f, compila bien.¿Por qué recibo un error al intentar llamar a una función de miembro de plantilla con un parámetro de tipo explícito?

template<typename T> 
struct A { 
    template<typename S> 
    void f() { } 
}; 

template<typename T> 
struct B : A<T> { 
    void g() { 
     this->f<int>(); 
    } 
}; 
+29

Te aplaudo no solo por encontrar este problema profano sino por nunca maldecir una vez al describirlo. –

Respuesta

129

Esto se debe a una disposición muy oscura de la norma en la que si tiene una plantilla que intenta acceder a una función de plantilla en un objeto cuyo tipo depende de un parámetro de plantilla, usted tiene que utilizar la palabra clave template de una manera extraña:

this->template f<int>(); 

Esto es similar a la rareza con typename que viene con tipos dependientes, excepto como se aplica a las funciones. En particular, si se omite la palabra clave template, hay una ambigüedad entre el análisis

this->f<int>() 

(lo que pretende), y

((this->f) < int) >() 

que no tiene sentido (de ahí su error). El uso de la palabra clave template aquí desambigua y obliga al compilador a reconocer que está buscando una llamada perfectamente válida para una función de miembro con plantilla en lugar de una masa de símbolos distorsionada.

Espero que esto ayude!

+2

Ya sabía algunas rarezas de sintaxis con plantillas, pero nunca había escuchado esto. – Gorpik

+0

@Gorpik: por eso debes evitar tales cosas :) – akira

+1

@templatetypedef: ¿sabes si algún compilador diagnostica esto correctamente? Estaría interesado en ver si CLang (que afirma tener un diagnóstico amistoso) sugeriría la inserción de 'plantilla' como una sugerencia de reparación, desafortunadamente no la tengo a mano. –

Cuestiones relacionadas