¿Cuál es la razón por la segunda soportes <> en la siguiente plantilla de función:

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

Esto surgió en ASÍ, pregunta donde se sugirió que hay entre paréntesis después de la falta de operator(), sin embargo, no pude encontrar la explicación.

Entiendo el significado si se trataba de un tipo de especialización (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 la función de las plantillas:

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) {}

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

#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);
}

De salida:

operator()(bool b)
template <> void operator()(int i)
  • la sintaxis anterior de doble paréntesis es muy extraño. Normalmente he visto operador(bool b), pero, ¿cómo el operador()(bool b) obras? ¿Cuál es el uso de la primera empty() ?
  • el nombre del método es operator() y toma un parámetro bool b … es el operador de llamada de función. Ver main en mi código de ejemplo, d(b)
InformationsquelleAutor stefanB | 2009-06-02

1 Comentario

  1. 31

    He buscado, y encontrado que es especificado por 14.5.2/2:

    Una clase local no tendrá miembro de plantillas. Reglas de control de acceso (cláusula 11) se aplican a los miembros de la plantilla de nombres. Un destructor no será miembro de la plantilla. Una normal (sin plantilla) función miembro con un nombre y un tipo y un miembro de la plantilla de función del mismo nombre, que podría ser utilizado para generar una especialización del mismo tipo, tanto puede ser declarada en una clase. Cuando ambos existen, en el uso de ese nombre y el tipo se refiere a la no-miembro de plantilla de menos explícito de la plantilla de lista de argumentos 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 condiciones Estándar, specialization se refiere a la función que se escribe mediante una explícita a la especialización y a la función generado mediante la creación de instancias, en cuyo caso tenemos que hacer con un generado de especialización. specialization no sólo se refiere a las funciones que se crean utilizando explícitamente especializado en una plantilla, para lo cual es a menudo utilizado.

    Conclusión: GCC se equivoca. Comeau, con el que también he probado 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 explícitamente especializados
    template<> void doh::operator()(bool i)

    Nota que no es quejarse de la especialización de la plantilla para int (sólo para bool), ya que no se refieren al mismo nombre y tipo: El tipo de función que la especialización que tiene es void(int), que es distinta de la del tipo de función de la no-miembro de plantilla de función, que es void(bool).

    • Así que si yo siga correctamente el ‘miembro de plantilla’ de arriba es un miembro con plantilla en «especialización» de Una estructura para int». Sentido, ahora, por lo que llamar a la ca.f() hará lo propio plantilla de resolución basada en el parámetro o explícita de la plantilla de lista de parámetros (cualquiera que sea el nombre correcto).
    • sí, bueno, el explícito especialización que hemos proporcionado para el f es de la especialización de Una estructura de tipo int. la base general de la plantilla de f existen para todas las especializaciones de A. es por eso Que podemos llamar también en un A<char>, como en el principal, por supuesto (pero no el uso de nuestro explícita de especialización, ya que era sólo para Un<int>::f<int>!) . Sí, de ca.f(cosas) hace su propia resolución, de hecho. Aquí, consulte 14.8.1/2 («Trailing argumentos de plantilla que puede ser deducido…»). Espero que esta ayuda 🙂
    • Sí muy bien, gracias por la investigación 🙂
    • Sólo estaba pensando que podría asustar a la gente mostrándoles esta especialmente si ellos no saben c++ y plantillas sintaxis: plantilla de <> plantilla <> void Una<int>::f<>(int) { } o mejor aún: plantilla de <> plantilla <> void Una<int>::operator()<>(int) { }
    • ahaha 😛 de hecho, es sospechoso. En cualquier caso, por favor tengan paciencia conmigo – mi último comentario (ahora retirado), dijo que para una primaria (base) de la definición de la plantilla, un argumento explícito lista será entregada: Ahora levantarse, yo, por supuesto, ver que era una tontería todo el camino 🙂
    • En template <> template <> void A<int>::f<>(int) { }, no es el <> justo antes de la lista de parámetros redundantes? El compilador ya sabe que usted se está refiriendo a la versión de la plantilla de los estados debido a la template <> template <>.

Dejar respuesta

Please enter your comment!
Please enter your name here