C ++重载了运算符声明和定义问题

时间:2009-06-10 16:47:06

标签: c++ declaration definition

我很难让这个工作

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) {
   ...  
}

我可以将其编译到一个没有问题的对象中,但是当其他函数尝试调用它时,会出现此错误(每次都使用&lt;&lt;&lt;使用)。

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

我做错了什么?

3 个答案:

答案 0 :(得分:8)

如果要在单独的编译单元中定义模板的实例(通常是这种情况),则无法在单独的cpp中定义模板方法。编译使用该模板类的编译单元时,编译器必须可以看到每个模板方法。因此,在跨cpps使用模板时,必须在标头中定义模板。模板实际上是生成类而不是自己的类的方法。因此,当编译器看到

YourClass<int>

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

的类型
YourClass<int>

及其所有方法,与

完全分开的方法
YourClass<float>

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

有关详细信息,请参阅我的回答here

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

答案 1 :(得分:4)

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

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

答案 2 :(得分:2)

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