2009-02-03 6 views
5

Me pregunto por qué el siguiente código de ejemplo artificial funciona perfectamente en Visual Studio 2005, pero genera un error en GCC ("función no coincidente para llamar" al llamar a Interpolate() Como se muestra abajo).GCC 4.0: "función no coincidente para llamar" en la función de plantilla

Además, ¿cómo puedo solucionar esto? Parece que el mensaje de error es solo un mensaje genérico porque GCC no tenía un mensaje más específico por el motivo real del problema y tenía que generar algo. Estoy un poco perdido sobre cómo proceder portar esta clase sin algunas soluciones realmente desagradables.

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&)' 

Gracias por su ayuda,

Adrian

Respuesta

9

No creo que necesita la plantilla existe en absoluto en la definición de la función, ya que está definida en línea con la clase

TMyPointTemplate Interpolate(const TMyPointTemplate &OtherPoint)const { 

debería hacer.

Y cuando utilizas la plantilla para definir la función no en línea, creo que necesitas la palabra clave class aquí como esta.

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

Excelente respuesta. ¡Muchas gracias por tu ayuda! :-) –

9

Evan's answer soluciona el problema, pero pensé que podría ser útil explicar por qué.

Como está escrito, Interpolate es una función de plantilla de miembro con un único parámetro de plantilla sin nombre "no tipo" (en lugar de un parámetro de plantilla de tipo que es casi seguro lo que pretendía). Para mostrar esto, podemos dar ese parámetro un nombre:

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

Y ahora podemos ver cómo llamar a esa función, sólo tenemos que proporcionar un valor para 't':

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

Adición clase o nombre de tipo antes de 'T' aquí, se declarará como un parámetro de plantilla de tipo. Sin embargo, hacer ese cambio dará como resultado un error ya que el identificador 'T' ya se está utilizando para el nombre del parámetro de plantilla en la plantilla de clase adjunta. Debemos cambiar el nombre del parámetro de plantilla para la plantilla de función de miembro:

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

Muy perspicaz. ¡Muchas gracias por tu ayuda! :-) –

Cuestiones relacionadas