为什么clang拒绝gcc接受的unordered_set定义?

时间:2018-08-25 00:20:05

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

我希望使用自己的哈希函数测试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);
        ^

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

2 个答案:

答案 0 :(得分:8)

尽管鲍姆·米特·奥根(Baum mit Augen)已经告诉过您这个问题,但我认为最好还是解释一下如何从错误消息中找出更多的信息。

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::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, std::__1::equal_to, std::__1::allocator >::__rehash' requested here
        __rehash(__n);
        ^

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

答案是肯定的。在这一点上,您可以简化代码以使方程中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将为您提供更多详细信息:

error: invalid operands to binary expression ('const node' and 'const node')
        a == b;
        ~ ^  ~
note: candidate function not viable: 'this' argument has type 'const node', but method is not marked const
        bool operator == (const node& n){return value == n.value;}
             ^

“方法未标记为const”准确地告诉您问题出在哪里。要解决此问题,请按照Baum mit Augen的答案进行操作,标记方法const

另一方面,如果答案是“不,您不应该能够比较两个const node对象”,那么问题将是“为什么unordered_set比较两个const node对象以及如何停止它”。为此,初始编译器消息的其余部分将告诉您是什么部分导致了该比较。您将必须自上而下,在每个步骤中弄清楚“这应该起作用吗?”如果是这样,找出它为什么不起作用。如果不是,请找出导致尝试的原因。

答案 1 :(得分:5)

您的比较运算符必须具有const的资格:

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

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

相关问题