【问题标题】:Why does clang reject this unordered_set definition gcc accepts?为什么 clang 拒绝这个 unordered_set 定义 gcc 接受?
【发布时间】:2019-01-31 10:37:55
【问题描述】:

我想用我自己的哈希函数测试unordered_set

#include<unordered_set>
#include<iostream>
#include<functional>
using namespace std;
struct node{
    size_t value;
    bool operator == (const node& n){return value == n.value;}
};
size_t h(const node& n){
    return n.value;
}
int main(){
    unordered_set<node, std::function<size_t(const node&)>> s2(3,h);//failed
    return 0;
}

我试图编译它,而 clang 给出了大量的错误:

clang++ m.cpp -std=c++11
In file included from m.cpp:1:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_set:324:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:659:21: error: invalid operands to binary
    expression ('const node' and 'const node')
        {return __x == __y;}
                ~~~ ^  ~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:2175:32: note: in instantiation of member
    function 'std::__1::equal_to<node>::operator()' requested here
                            key_eq()(__cp->__value_, __np->__next_->__value_);
                            ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:2121:9: note: in instantiation of member function
    'std::__1::__hash_table<node, std::__1::function<unsigned long (const node &)>, std::__1::equal_to<node>, std::__1::allocator<node> >::__rehash' requested here
        __rehash(__n);
        ^

我不太了解这里的错误信息,你能帮忙告诉我如何修复我的代码吗?

【问题讨论】:

    标签: c++ hash compilation clang unordered-set


    【解决方案1】:

    您的比较运算符必须是 const 合格的:

    bool operator == (const node& n) const {return value == n.value;}
                                     ^^^^^
    

    通过将运算符实现为非成员函数,可以轻松避免此类错误。有关更多信息和最佳实践,请参阅 What are the basic rules and idioms for operator overloading?

    【讨论】:

      【解决方案2】:

      虽然 Baum mit Augen 已经告诉您问题所在,但我认为最好也解释一下如何从错误消息中找出更多信息。

      clang++ m.cpp -std=c++11 在 m.cpp:1 中包含的文件中: 在 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_set:324 包含的文件中: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:659:21:错误:二进制操作数无效 表达式('const node' 和 'const node') {返回 __x == __y;} ~~~ ^ ~~~ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:2175:32:注意:在成员的实例化中 此处请求的函数'std::__1::equal_to::operator()' key_eq()(__cp->__value_, __np->__next_->__value_); ^ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:2121:9:注意:在成员函数的实例化中 'std::__1::__hash_table, std::__1::equal_to, std::__1::allocator >::__rehash' 在这里请求 __rehash(__n); ^

      第一部分告诉您将const node 与另一个const node 进行比较时出错。此时,您需要自行判断以确定您是否应该能够比较两个const nodes。

      这里的答案是肯定的。此时您可以简化代码以将unordered_set 排除在外,并让编译器为您提供有关该问题的更多信息:

      #include<cstddef>
      using namespace std;
      struct node{
          size_t value;
          bool operator == (const node& n){return value == n.value;}
      };
      int main(){
          const node a{}, b{};
          a == b;
      }
      

      如果你尝试编译这个,clang 会给你更多细节:

      错误:二进制表达式的操作数无效('const node' 和 'const node') a == b; ~ ^ ~ 注意:候选函数不可行:“this”参数的类型为“const node”,但方法未标记为 const bool operator == (const node& n){return value == n.value;} ^

      “方法未标记为 const” 可以准确地告诉您问题所在。要修复它,就像 Baum mit Augen 的回答一样,标记方法 const

      另一方面,如果答案是“不,您不应该能够比较两个 const node 对象”,那么问题将是“为什么 unordered_set 比较两个 const node对象,我该如何阻止它”。为此,初始编译器消息的其余部分将告诉您哪些部分导致了该比较。你必须从上到下,在每一步都弄清楚“这应该有效吗?”如果是,找出它为什么不工作。如果不是,请找出导致尝试的原因。

      【讨论】:

        猜你喜欢
        • 2021-06-11
        • 2014-09-02
        • 1970-01-01
        • 1970-01-01
        • 2016-10-20
        • 2017-01-16
        • 2015-07-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多