我希望使用自己的哈希函数测试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);
^
我在这里不太了解错误信息,您能帮我告诉我如何修复代码吗?
答案 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?。