anuncio de que no son fragmento de código que son válidos para ambas añadió la palabra clave y no añade, produciendo resultados diferentes en cada caso, incluso para las plantillas que tienen parámetros de tipo en lugar de números enteros.
#include <iostream>
struct A {
template<typename T>
static A f(T) {
return A();
}
template<typename T> operator T() { return T(); }
};
template<typename U>
int g() {
U u;
typedef A (*funcPtrType)(int());
return !(funcPtrType)u.f < int() > (0);
}
int main() {
std::cout << g<A>() << std::endl;
}
Esto da salida a 0
cuando se ejecuta sin la palabra clave template
añadió. Si agrega la palabra clave antes de f < int() >
, emite 1
.
Explicación
La versión sin la palabra clave analiza como
funcPtrType temp1 = (funcPtrType)u.f; // taking func address
bool temp2 = !temp1; // temp2 == false
bool temp3 = temp2 < int(); // temp3 == false
bool temp4 = temp3 > (0); // temp4 == false
return temp4;
Y la versión con la palabra clave analiza como
A temp1 = u.template f < int() > (0); // function call
funcPtrType temp2 = (funcPtrType) temp1; // temp2 == 0
bool temp3 = !temp2; // temp3 == true
return temp3;
en cuenta que temp2
es un puntero nulo (producido por return T()
). ¡Parses enteros diferentes, y ambos son válidos! Esto realmente necesita una forma de desambiguar, que es insertar la palabra clave template
según corresponda.