【问题标题】:Template class member function模板类成员函数
【发布时间】:2013-07-02 14:20:57
【问题描述】:

我有一个名为Time 的课程。只有两个私有成员:int hoursint minutes。公共访问说明符仅包含加法、减法等函数。

但是有一个特定的功能不符合我的要求。它在类中声明为public

这样编译:

Time Time::operator*(const int &mult)
{
   minutes = minutes*mult;
   hours = hours*mult + minutes/60;
   minutes %= 60;
   return *this;
}

但如果参数不是 int,而是 floatdouble,该怎么办?我想使用模板是最好的选择,而不是重载函数:

template <class T> Time Time::operator*(const T &mult)
{
   minutes = int(minutes*mult);
   hours = int(hours*mult) + minutes/60;
   minutes %= 60;
   return *this;
}

但是,这样写会产生编译错误:

error LNK2019: unresolved external symbol "public: class Time __thiscall Time::operator*<int>(int const &) " (??$?DH@Time@@QBE?AV0@ABH@Z) referenced in function _main

这意味着我不能在模板中使用运算符重载还是什么?

谢谢
罗伯特

【问题讨论】:

  • 您在哪里编写代码?模板成员函数需要在头文件(即.h或.hpp)中,而普通成员函数通常在实现文件(.cpp或.cxx)中定义
  • 你应该把你的模板代码放在头文件中。
  • 原型写在头文件中,定义写在实现文件中。喜欢这个功能。
  • 您不能将模板函数或类拆分为头文件和源文件,调用者需要完整的定义,如果函数在另一个源文件中,则缺少完整的定义。始终将模板化的类和函数全部放在头文件中。

标签: c++ class templates operator-overloading member-functions


【解决方案1】:

模板就像函数的模式。在您使用它们之前,它们必须被实例化。对于您的示例,您需要使用 T=int 对 Time::operator* 进行实例化,这是通过将函数中的每个 T 替换为 int 来获得的。

这种实例化可以通过两种方式发生:

首先,有显式实例化,您必须在其中为要使用它的所有类型实例化模板。 T=int 的 operator* 的显式实例化如下所示:

template Time Time::operator*<int>(const int &mult);

编译器需要查看定义来实例化模板,所以这里模板化函数的实现必须在同一个文件或包含文件中,但您可以将显式实例化与模板的实现放在一个实现中文件。

另一种方式是隐式实例化,模板在使用时在调用方进行实例化。对于此方法,模板实现必须在您使用模板时可见。实现这一点最简单的方法是将模板实现放在声明模板的头文件中。

所以你有两个选择,要么将 int 的显式实例化添加到实现文件中,要么将模板实现移动到头文件中。

【讨论】:

  • 看一下cmets的问题。
  • 因为答案不正确。您应该查看已发布到问题的 cmets 和链接。
  • 当我们在包含所有声明和定义的标头中创建模板时,编译过程在 .cpp 文件中发生两次,此标头包含:P
  • 在标题中:函数声明在相应的cpp中:函数定义和显式实例化(仅发生一次)。所有其他 cpp 文件都可以包含该标头,并使用在与标头(我的库)相对应的 cpp 中显式实例化的所有函数/类。链接器将完成剩下的工作。
  • @Antonio 不正确,你的意思是我没有说实例化只发生一次?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
相关资源
最近更新 更多