【问题标题】:Weird Linker error from overloaded << operator - C++来自重载 << 运算符的奇怪链接器错误 - C++
【发布时间】:2013-04-04 18:28:50
【问题描述】:

我编写了一个小的 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

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

【问题讨论】:

    标签: c++ debugging linker


    【解决方案1】:

    您应该将您的函数标记为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_;
        }
    

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

    如果您想知道为什么包含保护不能让您免于使用多个符号定义,您可能会发现 this Q&A on StackOverflow 很有用。

    【讨论】:

      【解决方案2】:

      包含保护仅防止文件被多次包含在同一翻译单元中。如果您将它包含在您单独编译的两个不同的.cpp 文件中(通常是.cpp 文件),则您有多个定义。

      把它放在一个实现文件中,只在头文件中留下一个声明。

      【讨论】:

      • 也谢谢你:)
      猜你喜欢
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 2011-01-19
      • 1970-01-01
      • 2018-06-16
      • 2016-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多