1

我很难让它发挥作用

file: myclass.hpp

Class MyClass {
public:
  template <class T>    
  MyClass &operator<<(const T &val);
};


file: myclass.cpp

template <class T>
MyClass &MyClass::operator<<(const T &val) {
   ...  
}

我可以毫无问题地将它编译成一个对象,但是当其他函数尝试调用它时,就会出现这个错误(每次使用 << 时)。

myclass.cpp: undefined reference to `MyClass& MyClass::operator<< <int>(int const&)'

我究竟做错了什么?

4

3 回答 3

8

如果您想在单独的编译单元中定义模板的实例(通常是这种情况),那么您不能在单独的 cpp 中定义模板方法。在编译使用该模板类的编译单元时,每个模板方法都必须对编译器可见。因此,当跨 cpps 使用模板时,模板必须在 header 中定义。模板实际上是生成类的方式,而不是自身生成类。因此,当编译器看到

YourClass<int>

它需要在编译时查看整个 YourClass 模板以生成一个名为

YourClass<int>

以及它的所有方法,它们与 say 有完全不同的方法

YourClass<float>

这意味着它必须查看所有 C++ 源代码。如果模板的这两种用法在单独的 cpp 中实例化,那么编译器生成两者的唯一方法是在一个标头中完全定义模板。

请参阅我的答案以获取更多信息。

感谢您的有用评论大大改善了这个答案

于 2009-06-10T16:49:46.757 回答
4

将运算符的定义放在.hpp而不是.cpp. 当为某些新类型实例化模板时,编译器需要能够看到模板的完整定义,以便它可以生成此专门化的代码。

C++ FAQ Lite中也有一些关于这种模板相关链接器错误和不同可能解决方案的问题和答案。

于 2009-06-10T16:49:34.620 回答
2

模板需要在头文件而不是 cpp 文件中定义。实际的实现是根据需要在每个编译单元中创建的,因为它们被使用。在这方面它们有点像宏。

于 2009-06-10T16:52:35.330 回答