Question

J'essaie de compiler un code C ++ visuel Microsoft à l'aide de G ++. Maintenant, je suis tombé sur une erreur de compilateur que je ne comprends vraiment pas. Le code (simplifié) ressemble à ceci:

template<int X> struct A {
    template<class Ret> static Ret call() {
        return 0;
    }
};

template<int X> struct B : A<X> {
    int f() {
        return A<X>::call<int>();
    }
};

Lorsque j'essaie de compiler cela avec G ++ (version 4.4.5), j'obtiens l'erreur suivante:

main.cpp: In member function int B<X>::f(): 
main.cpp:16: error: expected primary-expression before int 
main.cpp:16: error: expected ; before int
main.cpp:16: error: expected unqualified-id before > token

Si je supprime le type de modèle (RET) de la méthode A :: Call, le code se compile très bien. Quelqu'un peut-il voir ce qui ne va pas ici?

Merci!

Était-ce utile?

La solution

Vous avez besoin du template mot-clé:

return A<X>::template call<int>();

call est un nom dépendant, ce qui signifie que sa signification dépend d'un paramètre de modèle, qui n'est pas connu lorsque le processus du compilateur f(). Vous devez indiquer que call est un modèle de fonction en le préfixant avec le template mot-clé.

La même chose se produit lorsque vous essayez d'accéder à un type imbriqué: vous devez ajouter le typename mot-clé pour indiquer que le nom indique un type:

template <typename T>
struct A { typedef int type; };

template <typename T>
void f()
{
    typename A<T>::type i = 0; // notice "typename" here
}

Et parfois, vous devez même mélanger les deux:

template <typename T>
struct A
{
    template <typename U>
    struct inner { };
};

template <typename T>
void f()
{
    typename A<T>::template inner<int> var;
}

L'utilisation de ces deux mots clés est entièrement expliquée dans les réponses à cette question: Où et pourquoi dois-je mettre les mots clés «modèle» et «typename»? (Merci à @ Björn Pollex pour avoir trouvé le lien).

Autres conseils

A est un modèle, et sans savoir X le compilateur ne peut pas déterminer le contenu de A<X>. Surtout ça ne sait pas que call finira par être un modèle.

Pour dire qu'au compilateur, vous devez utiliser le template mot-clé:

template<int X> struct B : A<X> {
    int f() {
        return A<X>::template call<int>();
    }
};

Vous devez spécifier que la fonction que vous appelez est un modèle, car elle fait partie d'une classe de modèle. Le compilateur n'est pas conscient qu'un donné A<X> a une fonction de modèle nommée call, et donc vous devez l'aider.

template<int X> struct B : A<X> {
    int f() {
        return A<X>::template call<int>();
    }
};
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top