tipos template plantillas plantilla funciones funcion excepciones c++ templates

plantillas - template typename t c++



Plantillas: la función de plantilla no funciona bien con la función de miembro de plantilla de clase (2)

Este es un caso de prueba mínima de algún código que realmente tengo. Falla cuando intenta evaluar a.getResult<B>() :

test.cpp: In function ''void printStuff(const A&)'': test.cpp:6: error: expected primary-expression before ''>'' token test.cpp:6: error: expected primary-expression before '')'' token

El código es:

#include <iostream> template< class A, class B> void printStuff( const A& a) { size_t value = a.getResult<B>(); std::cout << value << std::endl; } struct Firstclass { template< class X > size_t getResult() const { X someInstance; return sizeof(someInstance); } }; int main(int, char**) { Firstclass foo; printStuff<Firstclass, short int>(foo); printStuff<Firstclass, double>(foo); std::cout << foo.getResult< double >() << std::endl; return 0; }

Si hago un comentario de la función printStuff y dónde se llama, la llamada foo.getResult< double >() compila bien y hace lo que se espera.

¿Tienes idea de lo que está pasando? He estado trabajando con código extensivamente templado por un tiempo y nunca he encontrado algo como esto.


Cuando se refiere a una plantilla que es miembro del tipo dependiente, debe anteponerla a una template palabra clave. Así es como debe verse la llamada a getResult dentro de printStuff

size_t value = a.template getResult<B>();

Esto es similar al uso de la palabra clave typename cuando se refiere a nombres de tipos anidados en un tipo dependiente. Por alguna razón, el bit sobre typename con tipos anidados es bastante conocido, pero el requisito similar para la template con plantillas anidadas es relativamente desconocido.

Tenga en cuenta que la estructura de sintaxis general es un poco diferente sin embargo. El nombre de tipo siempre se coloca delante del nombre completo del tipo, mientras que la template se inserta en el medio.

Nuevamente, esto solo es necesario cuando accede a un miembro de plantilla de un tipo dependiente , que en el ejemplo anterior sería A en printStuff . Cuando llamas a foo.getResult<> en main el tipo de foo no es dependiente, por lo que no es necesario incluir la palabra clave de la template .


Su código está mal formado según el estándar C ++ 14.2 / 4:

Cuando aparece el nombre de una especialización de plantilla de miembro después . o -> en una expresión de postfijo , o después de especificador de nombre anidado en un id-calificado , y la expresión de postfijo o id-calificado depende explícitamente de un parámetro de plantilla (14.6.2), el nombre de la plantilla de miembro debe ser prefijado por la template la palabra clave. De lo contrario, se asume que el nombre no es una plantilla.

Por lo tanto, debe escribir size_t value = a.template getResult<B>();