【问题标题】:Linker error: Template relational operator链接器错误:模板关系运算符
【发布时间】:2013-06-10 12:21:45
【问题描述】:

为什么这段代码会给我一个链接器错误,我该如何解决?

架构 x86_64 的未定义符号:“operator==(foo const&, foo const&)”,引用自:main.old 中的 _main:未找到架构 x86_64 的符号

template<typename T>
class foo {
  //friends get access to the private member t
  friend bool operator==(const foo<T> &lhs, const foo<T> &rhs);
  T t;
};

template<typename T>
bool operator==(const foo<T> &lhs, const foo<T> &rhs) {
  return lhs.t == rhs.t;
}

int main(int,char**) {
  foo<int> f1, f2;
  if (f1 == f2)
    ;
  return 0;
}

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    这是您的代码的修复:

    template<typename T>
    class foo; // Forward declaration
    
    template<typename T> // Need to define or declare this before the class
    bool operator==(const foo<T> &lhs, const foo<T> &rhs) {
      return lhs.t == rhs.t; 
    }
    
    template<typename T>
    class foo {
      // Notice the little <> here denoting a specialization
      friend bool operator==<>(const foo<T> &lhs, const foo<T> &rhs);
      T t;
    };
    

    【讨论】:

    • 先声明函数就足够了。
    • @SebastianRedl: foo 在类定义之前是未知的,需要前向声明或在类内或类后定义。
    • @JesseGood:我认为 Sebastian 的意思是转发声明 operator== 就足够了。由于它可以编译任何一种方式,因此是否有必要是一个悬而未决的问题。 +1,无论如何。很好的答案。
    • 我的意思是你可以在类模板定义之前声明 operator == 模板,然后再定义 operator == 模板。因为我更喜欢在使用它的任何函数之前出现类定义,所以我更喜欢这样做。我并不是建议您可以省略类模板声明。
    • @SebastianRedl:啊,我现在明白了。我将其编辑为define or declare。谢谢。
    【解决方案2】:

    operator== 是一个函数模板,但友谊声明并没有反映这一点。这是修复它的一种方法:

    template <class U>
    friend bool operator==(const foo<U> &lhs, const foo<U> &rhs);
    

    一个非常小的故障是它让operator==&lt;int&gt; 朋友访问foo&lt;string&gt;。出于这个原因,我认为@JesseGood 的修复更简洁,尽管(自相矛盾地)更冗长。

    【讨论】:

      【解决方案3】:

      需要再次指定模板类型,但与类模板类型不同:

      template<typename V>
      friend bool operator==(const foo<V> &lhs, const foo<V> &rhs);
      

      【讨论】:

        【解决方案4】:

        重载运算符时,避免使用友元函数;您需要将您的函数定义为公共类成员,并使其只接受一个参数(而不是两个)。

        template<typename T>
        class foo {
          //public function allowing access to the private member t
          public:
          bool operator==(  foo<T> &rhs)
          {
              return t == rhs.t;
          }
          private:
          T t;
        };
        
        
        int main(int,char**) {
          foo<int> f1, f2;
          if (f1 == f2)
            ;
          return 0;
        }
        

        【讨论】:

        • 不,一般来说你不会,因为这会在为左侧和右侧完成的自动转换之间引入不对称性。
        猜你喜欢
        • 2011-03-01
        • 2016-05-05
        • 1970-01-01
        • 1970-01-01
        • 2015-01-28
        • 1970-01-01
        • 1970-01-01
        • 2018-09-18
        • 1970-01-01
        相关资源
        最近更新 更多