GCC 4.0:模板功能中“没有匹配的函数调用”

时间:2021-02-18 18:48:45

I am wondering why the following contrived example code works perfectly fine in Visual Studio 2005, but generates an error in GCC ("no matching function to call" when calling Interpolate() as shown below).

我想知道为什么以下设计的示例代码在Visual Studio 2005中完美运行,但在GCC中生成错误(“调用Interpolate()时没有匹配的函数调用”,如下所示)。

Also, how do I work around this? It seems that the error message is just a generic message because GCC did not have a more specific message for the actual reason of the problem and it had to output something. I'm a bit at a loss on how to proceed porting this class without some really ugly workarounds.

另外,我该如何解决这个问题?似乎错误消息只是一个通用消息,因为GCC没有针对问题的实际原因的更具体的消息,它必须输出一些东西。我有点不知道如何在没有一些非常难看的变通方法的情况下继续移植这个类。

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

Thanks for your help,

谢谢你的帮助,

Adrian

2 个解决方案

#1


I don't think you need the template there at all in the function definition, since it is defined inline with the class

我认为在函数定义中根本不需要模板,因为它是与类一起内联定义的

TMyPointTemplate Interpolate(const TMyPointTemplate &OtherPoint)const {

should do.

And when you do use the template for defining the function not inline, I think you need the class keyword in there like this.

当你使用模板来定义不内联的函数时,我认为你需要像这样的class关键字。

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

#2


Evan's answer addresses the issue, but I thought it might be useful to explain why.

Evan的回答解决了这个问题,但我认为解释原因可能有用。

As written, Interpolate is a member template function with a single unnamed 'non type template parameter' (rather than a type template parameter which is almost certainly what you intended). To show this, we can give that parameter a name:

如上所述,Interpolate是一个成员模板函数,带有一个未命名的“非类型模板参数”(而不是类型模板参数,几乎可以肯定你的意图)。为了显示这一点,我们可以为该参数指定一个名称:

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

And we can now see how to call that function, we just need to provide a value for 't':

我们现在可以看到如何调用该函数,我们只需要为't'提供一个值:

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

Adding class or typename before 'T' here, will declare it as a type template parameter. However, making just that change will result in an error since the identifier 'T' is already being used for the template parameter name in the enclosing class template. We must change the name of the template parameter for the member function template:

在此处“T”之前添加类或类型名称,将其声明为类型模板参数。但是,仅进行该更改将导致错误,因为标识符“T”已用于封闭类模板中的模板参数名称。我们必须更改成员函数模板的模板参数的名称:

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

#1


I don't think you need the template there at all in the function definition, since it is defined inline with the class

我认为在函数定义中根本不需要模板,因为它是与类一起内联定义的

TMyPointTemplate Interpolate(const TMyPointTemplate &OtherPoint)const {

should do.

And when you do use the template for defining the function not inline, I think you need the class keyword in there like this.

当你使用模板来定义不内联的函数时,我认为你需要像这样的class关键字。

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

#2


Evan's answer addresses the issue, but I thought it might be useful to explain why.

Evan的回答解决了这个问题,但我认为解释原因可能有用。

As written, Interpolate is a member template function with a single unnamed 'non type template parameter' (rather than a type template parameter which is almost certainly what you intended). To show this, we can give that parameter a name:

如上所述,Interpolate是一个成员模板函数,带有一个未命名的“非类型模板参数”(而不是类型模板参数,几乎可以肯定你的意图)。为了显示这一点,我们可以为该参数指定一个名称:

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

And we can now see how to call that function, we just need to provide a value for 't':

我们现在可以看到如何调用该函数,我们只需要为't'提供一个值:

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

Adding class or typename before 'T' here, will declare it as a type template parameter. However, making just that change will result in an error since the identifier 'T' is already being used for the template parameter name in the enclosing class template. We must change the name of the template parameter for the member function template:

在此处“T”之前添加类或类型名称,将其声明为类型模板参数。但是,仅进行该更改将导致错误,因为标识符“T”已用于封闭类模板中的模板参数名称。我们必须更改成员函数模板的模板参数的名称:

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