c++ - 来自重载 << 运算符的奇怪链接器错误 - C++

标签 c++ debugging linker

我编写了一个小型 Timer 类来检查我的代码的性能。源代码可以在这里找到 http://pastebin.com/i1PX2VPN (稍后我将在此处突出显示重要部分)

现在我遇到了一个非常奇怪的错误:上面链接的代码在文件 Timer.hpp 中。我在我的 main.cpp 中使用了这个文件,它工作得很好。但是,我还想在另一个源文件中使用它,然后,只要添加一个

  #include <Timer.hpp> 

进入下一个源文件,我得到以下链接器错误:

  ld: duplicate symbol operator<<(std::basic_ostream<char, std::char_traits<char> >&, Timer const&) in /var/folders/XZ/XZ93KWBqG0SR1aCVpTCVQE+++TI/-Tmp-//ccyaHyyU.o and /var/folders/XZ/XZ93KWBqG0SR1aCVpTCVQE+++TI/-Tmp-//ccETAaTw.o
  collect2: ld return 1 as exit status
  make: *** [debugd] Error 1

函数是

 std::ostream& operator<<(std::ostream& os, const Timer& t) {
         return os << std::scientific << std::setw(8)  << std::setprecision(3)
                            << t.timeTotal_ << " \t " << t.timeMin_ << " \t " <<          t.timeMax_;
   }

没什么特别的……再一次:只要它只包含在我的 main.cpp 中,它就可以工作

显然这似乎是运算符的多个定义(?)的问题。但我不明白为什么或如何解决它。我使用 include-guards 来避免它被多次包含。

我已经检查过在我从未听说过的 C++ 库中是否还有另一个 Timer 类,这显然不是这种情况(重命名类不会改变任何东西)...

在 Timer.hpp 中,还定义了另一个类,也有自己的 operator<< 重载。我不知道这是否重要,我只是觉得我应该提一下

所以...我期待着您的想法,谢谢

最佳答案

您应该将您的函数标记为inline,因为它是一个全局函数,其定义被多个翻译单元包含。

    inline std::ostream& operator<<(std::ostream& os, const Timer& t) {
//  ^^^^^^
         return os << std::scientific << std::setw(8)  << std::setprecision(3)
               << t.timeTotal_ << " \t " << t.timeMin_ << " \t " 
               << t.timeMax_;
    }

或者,您可以将函数的声明保留在 header 中,并将定义放在一个单独的 .cpp 文件中。

如果您想知道为什么 include guards 没有将您从多个符号定义中拯救出来,您可能会发现 this Q&A on StackOverflow 很有用。

关于c++ - 来自重载 << 运算符的奇怪链接器错误 - C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15818901/

相关文章:

Eclipse 中 Scientific Linux 上的 C++14

c++ - Unresolved external (抽象类构造函数/析构函数)

c - 如何查找链接到同一应用程序的两个库之间的所有符号冲突(引用和未引用的符号)?

C++ - 整数类型的数组

c++ - 如何在不使用循环的情况下进行排序

C++货币输出

javascript - Chrome 浏览器中的“代码片段”选项卡有什么用

c++ - 如何检查 LLDB 是否从共享库加载了调试符号?

debugging - 如何调试 Google Apps 脚本(又名 Logger.log 记录到哪里?)

ffmpeg - 链接 libavcodec os x ffmpeg ApplicationServices.framework