【问题标题】:unordered_set with custom predicate make linker error (duplicate symbol)带有自定义谓词的 unordered_set 使链接器错误(重复符号)
【发布时间】:2013-06-02 17:24:14
【问题描述】:

我遇到了一个小问题:我有一个包含结构的 unordered_set。我已经实现了哈希函数。但是当我第一次编译我的程序时,我得到了一些编译器错误,说我没有实现一个重载的“operator==”。

问题是当我声明我的重载时:

bool operator==(mapPoint const& p1, mapPoint const& p2){
    return p1.x == p2.x && p1.y == p2.y;
}

我遇到了一些链接器错误。在包含标头的每个文件中,我都收到错误消息(复制符号 __XXXX_mapPointS1_)。

事实上,当它被放入实现文件时,它工作得很好,我将它与 unordered_set 一起使用。

我的问题是,我该如何解决这个问题?除了编译器之外,还有很多我无法理解的魔法。汉克斯

【问题讨论】:

标签: c++ duplicate-symbol


【解决方案1】:

当你把它放在一个实现文件中时,你就明白它没有那个问题。

C++ 编译器没有任何头文件和实现文件的概念。它只知道“翻译单元”,即 cpp 文件。头文件包含在 C 预处理器中。编译器只看到一个文件。 如果您在包含多个 cpp 文件的头文件中定义了一个函数,并且该函数具有外部链接,则链接器将抱怨重复定义。

通常,您应该只保留内联函数的标头定义。

如果你仍然想这样做,你必须避免外部链接,要么通过声明函数内联,要么声明它为静态,或者通过在没有名称的命名空间内声明它(这是 C++ 内部定义东西的方式到翻译单元)。

namespace // local
{
    bool operator==(mapPoint const& p1, mapPoint const& p2)
        { return p1.x == p2.x && p1.y == p2.y; }
}

或者,有点丑陋和 C-ish:

static bool operator==(mapPoint const& p1, mapPoint const& p2)
    { return p1.x == p2.x && p1.y == p2.y; }

或者,因为这个函数看起来很适合内联:

inline bool operator==(mapPoint const& p1, mapPoint const& p2)
    { return p1.x == p2.x && p1.y == p2.y; }

【讨论】:

  • 感谢 migle 的帮助。让它像一个魅力一样内联工作。我不得不在不使用它的情况下给出 (==) 的一种实现(因为 unordered_set),这让我遇到了很大的麻烦。我在标头中尝试了命名空间技巧,但编译器抱怨找不到它。所以我有点困惑,因为在 c++ 书籍中,他们将 (==) 内容裸露在实现文件中,女巫对我来说是个问题。我真的很感谢你的帮助。谢谢!
  • 可以放到实现文件中,只要其他翻译单元看到函数的声明即可。也就是说,extern bool operator ==(mapPoint const&, mapPoint const&); 仅此而已(函数已声明但未定义)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-15
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多