30 votes

Format de spécialisation du modèle de fonction

Quelle est la raison de la deuxième entre crochets <> dans la suite de modèle de fonction:

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

J'en DONC, la question , où il a été suggéré qu'il y a entre parenthèses manquantes après l' operator(), cependant je ne pouvais pas trouver l'explication.

Je comprends le sens si c'était un type de spécialisation (plein de spécialisation) de la forme:

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

Cependant, pour les modèles de fonction:

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

Où cela s'inscrit dans ce scénario?:

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

Exemple de code qui semble fonctionner et ne donne pas d'avertissement/d'erreur (gcc 3.3.3 utilisé):

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

Sortie:

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

31voto

Johannes Schaub - litb Points 256113

J'ai regardé, et a constaté qu'il est spécifié par 14.5.2/2:

Un local de classe n'ont pas de modèles de membre. Règles de contrôle d'accès (clause 11) s'appliquent qu'aux membres les noms de modèle. Un destructeur ne doit pas être un membre de modèle. Un normal (non du modèle) membre de la fonction avec un nom et d'un type et d'une fonction membre template du même nom, qui pourrait être utilisé pour générer une spécialisation du même type, peut à la fois être déclarée dans une classe. Lorsque les deux existent, une utilisation de ce nom et le type se réfère à la non-modèle de membre, sauf si explicitement un argument de modèle de liste est fournie.

Et il donne un exemple:

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
}

Notez que, dans des conditions Standard, specialization se réfère à la fonction que vous écrivez à l'aide d'un explicite de la spécialisation et de la fonction générée à l'aide de l'instanciation, auquel cas nous avons à faire avec un générés spécialisation. specialization ne se réfère pas seulement à des fonctions que vous créez en utilisant explicitement spécialisée un modèle, pour qui il est souvent utilisé.

Conclusion: GCC s'il se trompe. Comeau, avec qui j'ai aussi testé le code, il obtient le droit et les enjeux d'un diagnostic:

"ComeauTest.c", ligne 16: erreur: "void doh::operator()(bool)" n'est pas une entité qui peut être explicitement spécialisés template<> void doh::operator()(bool i)

Notez qu'il n'est pas à se plaindre au sujet de la spécialisation du modèle de int (uniquement pour bool), car il ne se réfèrent pas à la même nom et type: Le type de fonction que la spécialisation auraient est - void(int), qui est distincte de la fonction de type de la non-modèle de fonction de membre de qui est - void(bool).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X