我想知道为什么以下设计的示例代码在Visual Studio 2005中完美运行,但在GCC中生成错误(“调用Interpolate()时没有匹配的函数调用”,如下所示)。
另外,我该如何解决这个问题?似乎错误消息只是一个通用消息,因为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&)'
感谢您的帮助,
阿德里安
答案 0 :(得分:9)
我认为在函数定义中根本不需要模板,因为它是与类一起内联定义的
TMyPointTemplate Interpolate(const TMyPointTemplate &OtherPoint)const {
应该这样做。
当你使用模板来定义非内联函数时,我认为你需要像这样的class关键字。
template<class T> // <- here
TMyPointTemplate<T> TMyPointTemplate<T>::Interpolate(const TMyPointTemplate<T> &OtherPoint)const {
答案 1 :(得分:9)
Evan的answer解决了这个问题,但我认为解释原因可能有用。
如上所述,Interpolate是一个成员模板函数,带有一个未命名的“非类型模板参数”(而不是类型模板参数,几乎可以肯定你的意图)。为了表明这一点,我们可以为该参数命名:
template<T t> TMyPointTemplate<T> Interpolate
(const TMyPointTemplate<T> &OtherPoint)const
我们现在可以看到如何调用该函数,我们只需要为't'提供一个值:
Geo::IntegerPoint Point3=Point1.Interpolate <0> (Point2);
在此处“T”之前添加类或 typename ,会将其声明为类型模板参数。但是,仅进行该更改将导致错误,因为标识符“T”已用于封闭类模板中的模板参数名称。我们必须更改成员函数模板的模板参数的名称:
template <class T>
class TMyPointTemplate
{
public:
//...
template<class S> TMyPointTemplate<T> Interpolate
(const TMyPointTemplate<S> &OtherPoint) const
{
return ...;
}
};