Pregunta

¿Cuál es la razón para el segundo paréntesis angulares <> en la plantilla de función siguiente:

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

Esto me ocurrió en Así que la pregunta donde se sugirió que hay soportes desaparecidos tras operator(), sin embargo no pude encontrar la explicación.

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

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

Sin embargo, para las plantillas de función:

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 scenarion:?

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

Ejemplo de código que parece funcionar y no da ninguna advertencia / error (3.3.3 gcc utilizado):

#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)
¿Fue útil?

Solución

He mirado hacia arriba, y encontró que se especifica mediante 14.5.2 / 2:

  

Una clase local no deberá tener plantillas miembros. reglas de control de acceso (cláusula 11) se aplican a los nombres de plantilla miembro. Un destructor no será miembro de una plantilla. A (no molde) la función normal miembro con un nombre y tipo dado y una plantilla de función miembro del mismo nombre, que podría ser utilizado para generar una especialización del mismo tipo, puede tanto ser declarada en una clase. Cuando ambos existen, un uso de ese nombre y tipo se refiere a la no miembro de la plantilla a menos que una lista de argumentos plantilla explícita se suministra.

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, specialization se refiere a la función se escribe utilizando un especialización explícita ya la función generada a partir de ejemplificación, en cuyo caso tenemos que ver con una especialización generada. specialization no sólo se refiere a las funciones que se crean explícitamente usando una plantilla especializada, para lo cual se utiliza a menudo solamente.

Conclusión: GCC se equivoca. Comeau, con la que yo 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 especializada de forma explícita     template<> void doh::operator()(bool i)

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top