pueden populares poner permite para los hashtags funcionan cuantos aparezco c++ templates syntax template-specialization

c++ - populares - no aparezco en los hashtag de instagram



Formato de especializaciĆ³n de plantilla de funciĆ³n (1)

¿Cuál es el motivo de los segundos paréntesis <> en la siguiente plantilla de función?

template<> void doh::operator()<>(int i)

Esto surgió en la pregunta SO, donde se sugirió que faltaban corchetes después del operator() , sin embargo, no pude encontrar la explicación.

Entiendo el significado si era una especialización de tipo (especialización completa) de la forma:

template< typename A > struct AA {}; template<> struct AA<int> {}; // hope this is correct, specialize for int

Sin embargo, para plantillas de funciones:

template< typename A > void f( A ); template< typename A > void f( A* ); // overload of the above for pointers template<> void f<int>(int); // full specialization for int

¿Dónde encaja esto en este escenario ?:

template<> void doh::operator()<>(bool b) {}

Código de ejemplo que parece funcionar y no da ninguna advertencia / error (se usa gcc 3.3.3):

#include <iostream> using namespace std; struct doh { void operator()(bool b) { cout << "operator()(bool b)" << endl; } template< typename T > void operator()(T t) { cout << "template <typename T> void operator()(T t)" << endl; } }; // note can''t specialize inline, have to declare outside of the class body template<> void doh::operator()(int i) { cout << "template <> void operator()(int i)" << endl; } template<> void doh::operator()(bool b) { cout << "template <> void operator()(bool b)" << endl; } int main() { doh d; int i; bool b; d(b); d(i); }

Salida:

operator()(bool b) template <> void operator()(int i)


Lo busqué y descubrí que está especificado en 14.5.2 / 2:

Una clase local no debe tener plantillas de miembros. Las reglas de control de acceso (cláusula 11) se aplican a los nombres de plantilla de miembro. Un destructor no debe ser una plantilla de miembro. Una función de miembro normal (sin plantilla) con un nombre y tipo dados y una plantilla de función miembro con el mismo nombre, que podría usarse para generar una especialización del mismo tipo, ambos pueden declararse en una clase. Cuando ambos existen, el uso de ese nombre y tipo se refiere al miembro que no es de plantilla a menos que se proporcione una lista explícita de argumentos de plantilla.

Y proporciona un ejemplo:

template <class T> struct A { void f(int); template <class T2> void f(T2); }; template <> void A<int>::f(int) { } // non-template member template <> template <> void A<int>::f<>(int) { } // template member int main() { A<char> ac; ac.f(1); //non-template ac.f(’c’); //template ac.f<>(1); //template }

Tenga en cuenta que en términos estándar, la specialization refiere a la función que se escribe utilizando una especialización explícita y a la función generada mediante instanciación, en cuyo caso tenemos que ver con una especialización generada. specialization no solo se refiere a las funciones que crea usando explícitamente una plantilla especial, para la cual a menudo solo se usa.

Conclusión: GCC se equivoca. Comeau, con el que también probé el código, lo hace bien y emite un diagnóstico:

"ComeauTest.c" , línea 16: error: "void doh::operator()(bool)" no es una entidad que puede ser template<> void doh::operator()(bool i) explícitamente especializada template<> void doh::operator()(bool i)

Tenga en cuenta que no se queja de la especialización de la plantilla para int (solo para bool ), ya que no se refiere al mismo nombre y tipo: El tipo de función que la especialización tendría es void(int) , que es distinto del tipo de función de la función miembro no plantilla, que es void(bool) .