the template guide geeksforgeeks example c++ templates

c++ - template - expresión primaria esperada antes de ">" en g++ pero no en el compilador de microsoft



template function c++ (1)

Este código no se compila en g ++ (Ubuntu / Linaro 4.6.3-1ubuntu5) 4.6.3, con este error

test.cpp: In function ‘T mul(V&, V&)’: test.cpp:38:27: error: expected primary-expression before ‘>’ token test.cpp:38:29: error: expected primary-expression before ‘)’ token test.cpp:38:53: error: expected primary-expression before ‘>’ token test.cpp:38:55: error: expected primary-expression before ‘)’ token

pero se compila y ejecuta correctamente en Microsoft C / C ++ Optimizing Compiler versión 15.00.21022.08 para x64

#include <iostream> #include <complex> template <class T> class SM { public: T value; }; template <class T> class SC : public SM<T> { }; class PSSM { public: template <class T> T & getSC() { return sc; } private: SC<double> sc; }; class USSM { public: template <class T> T & getSC() { return sc; } private: SC<std::complex<double> > sc; }; template <class T, class V> T mul( V & G, V & S) { return (G.getSC<SC<T> >().value * S.getSC<SC<T> >().value); // error is here } int main() { PSSM p; PSSM q; p.getSC<SC<double> >().value = 5; q.getSC<SC<double> >().value = 3; std::cout << mul<double>(p,q); }

No entiendo dónde está el problema. ¿Alguien puede entender cómo solucionarlo o explicar la naturaleza del problema en g ++?


El problema es sintáctico. Debe usar el desambiguador de template en este caso, para que su invocación de una plantilla de función miembro se analice correctamente:

return (G.template getSC<SC<T> >().value * S.template getSC<SC<T> >().value); // ^^^^^^^^^ ^^^^^^^^^

Este desambiguador ayuda al compilador a reconocer que lo que sigue a G. es una especialización de plantilla de miembro y no, por ejemplo, un miembro de datos llamado getSC seguido de un < (menor que).

La referencia estándar para el desambiguador de template es el párrafo 14.2 / 4 de la norma C ++ 11:

Cuando el nombre de una plantilla de miembro de especialización aparece después . o -> en una expresión de postfix o después de un especificador de nombre anidado en una id-calificada , y la expresión de objeto de la expresión de postfix depende del tipo o el especificador de nombre anidado en la id-calificada se refiere a tipo dependiente, pero el nombre no es un miembro de la instanciación actual (14.6.2.1), el nombre de la plantilla de miembro debe ir precedido por la template palabra clave. De lo contrario, se asume que el nombre nombra una no-plantilla. [ Ejemplo:

struct X { template<std::size_t> X* alloc(); template<std::size_t> static X* adjust(); }; template<class T> void f(T* p) { T* p1 = p->alloc<200>(); // ill-formed: < means less than T* p2 = p->template alloc<200>(); // OK: < starts template argument list T::adjust<100>(); // ill-formed: < means less than T::template adjust<100>(); // OK: < starts template argument list }

- ejemplo final ]