2009-02-03 7 views
5

Je me demande pourquoi le code d'exemple artificiel suivant fonctionne parfaitement dans Visual Studio 2005, mais génère une erreur dans GCC ("aucune fonction correspondante à appeler" lors de l'appel d'Interpolate() comme indiqué ci-dessous).GCC 4.0: "aucune fonction correspondante à appeler" dans la fonction de gabarit

En outre, comment puis-je contourner ce problème? Il semble que le message d'erreur est simplement un message générique car GCC n'a pas de message plus spécifique pour la raison du problème et il doit sortir quelque chose. Je suis un peu sur la façon de poursuivre le portage de cette classe sans certaines solutions de contournement vraiment moche.

namespace Geo 
{ 
    template <class T> 
    class TMyPointTemplate 
    { 
     T X,Y; 
    public: 
     inline TMyPointTemplate(): X(0), Y(0) {} 
     inline TMyPointTemplate(T _X,T _Y): X(_X), Y(_Y) {} 
     inline T GetX()const { return X; } 
     inline T GetY()const { return Y; } 
     //... 
     template<T> TMyPointTemplate<T> Interpolate(const TMyPointTemplate<T> &OtherPoint)const 
     { 
      return TMyPointTemplate((X+OtherPoint.GetX())/2,(Y+OtherPoint.GetY())/2); 
     }   
    }; 
    typedef TMyPointTemplate<int> IntegerPoint; 
} 

Geo::IntegerPoint Point1(0,0); 
Geo::IntegerPoint Point2(10,10); 
Geo::IntegerPoint Point3=Point1.Interpolate(Point2); //GCC PRODUCES ERROR: no matching function for call to 'Geo::TMyPointTemplate<int>::Interpolate(Geo::IntegerPoint&)' 

Merci pour votre aide,

Adrian

Répondre

9

Je ne pense pas que vous devez utiliser le modèle là à tous dans la définition de la fonction, puisqu'elle est définie en ligne avec la classe

TMyPointTemplate Interpolate(const TMyPointTemplate &OtherPoint)const { 

devrait le faire.

Et quand vous utilisez le modèle pour définir la fonction pas en ligne, je pense que vous avez besoin du mot-clé class comme ceci.

template<class T> // <- here 
TMyPointTemplate<T> TMyPointTemplate<T>::Interpolate(const TMyPointTemplate<T> &OtherPoint)const { 
+0

Excellente réponse. Merci beaucoup pour votre aide! :-) –

9

Le problème answer d'Evan résout le problème, mais j'ai pensé qu'il pourrait être utile d'expliquer pourquoi. Comme indiqué, Interpolate est une fonction de modèle de membre avec un seul 'paramètre de modèle non type' sans nom (plutôt qu'un paramètre de modèle de type qui est presque certainement ce que vous vouliez). Pour le montrer, nous pouvons donner ce paramètre un nom:

template<T t> TMyPointTemplate<T> Interpolate 
     (const TMyPointTemplate<T> &OtherPoint)const 

Et nous pouvons maintenant voir comment appeler cette fonction, nous avons juste besoin de fournir une valeur pour « t »:

Geo::IntegerPoint Point3=Point1.Interpolate <0> (Point2); 

Ajout class ou tapez le nom avant «T» ici, le déclarera comme un paramètre de modèle de type. Cependant, faire juste ce changement se traduira par une erreur puisque l'identificateur 'T' est déjà utilisé pour le nom du paramètre de modèle dans le modèle de classe englobant. Nous devons modifier le nom du paramètre de modèle pour le modèle de fonction membre:

template <class T> 
class TMyPointTemplate 
{ 
public: 
    //... 
    template<class S> TMyPointTemplate<T> Interpolate 
       (const TMyPointTemplate<S> &OtherPoint) const 
    { 
    return ...; 
    }      
}; 
+0

Très perspicace en effet. Merci beaucoup pour votre aide! :-) –

Questions connexes