Reputation: 10507
I wish to test unordered_set
with my own hash function:
#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;
}
I tried to compile it, while clang gives a huge amount of errors:
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);
^
I don't quite get the error information here, would you help to tell how I fix my code?
Upvotes: 4
Views: 586
Reputation:
Although Baum mit Augen already told you the problem, I think it is a good idea to also explain how you could figure out more from the error message.
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); ^
This first part is telling you that there is an error comparing a const node
to another const node
. At this point, you will need to exercise your own judgement to determine whether you should be able to compare two const node
s.
The answer here is yes. At which point you can simplify your code to take unordered_set
out of the equation, and get the compiler to give you more information about the problem:
#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;
}
If you try to compile this, clang will give you more details:
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;} ^
"method is not marked const" tells you exactly what the problem is. To fix it, as in Baum mit Augen's answer, mark the method const
.
If, on the other hand, the answer would have been "no, you are not supposed to be able to compare two const node
objects", then the question would be "why is unordered_set
comparing two const node
objects and how can I stop it". For that, the rest of the initial compiler message will tell you what parts are causing that comparison. You would have to go from top to bottom, figuring out at each step "is this supposed to work?" If it is, figure out why it is not working. If it is not, figure out what is causing the attempt.
Upvotes: 8
Reputation: 50053
Your comparison operator must be const
qualified:
bool operator == (const node& n) const {return value == n.value;}
^^^^^
Mistakes like this are easy to avoid by implementing the operator as a non-member function. See What are the basic rules and idioms for operator overloading? for more information and best practices.
Upvotes: 5