【问题标题】:C++ overloaded operator declaration and definition problemsC++重载运算符声明和定义问题
【发布时间】:2009-06-10 16:47:06
【问题描述】:

我很难让它工作

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

我做错了什么?

【问题讨论】:

    标签: c++ declaration definition


    【解决方案1】:

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

    YourClass<int>
    

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

    的类型
    YourClass<int>
    

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

    YourClass<float>
    

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

    查看我的回答 here 了解更多信息。

    感谢有用的 cmets 大大改进了这个答案

    【讨论】:

    • +1,大体上是正确的,但实际上您可以将模板定义放在 .cpp 文件中,只要您手动实例化将在应用程序中使用的所有类型。即在定义后添加:'template class YourClass;模板类 YourClass; ...'
    • 这是用于 GNU 黄金链接器的技术:stackoverflow.com/questions/280162/…airs.com/ian/gold-slides.pdf。你的这个错误断言阻止了我对你的两个答案投赞成票:(
    • 谢谢,我还没有完全意识到这一点。更新了我的答案。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-22
        相关资源
        最近更新 更多