Why does clang reject this unordered_set definition gcc accepts?
Why does clang reject this unordered_set definition gcc accepts?
I wish to test unordered_set with my own hash function:
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;
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?
2 Answers
2
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.
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 nodes.
const node
const node
const node
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:
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;
If you try to compile this, clang will give you more details:
"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.
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.
const node
unordered_set
const node
Your comparison operator must be const qualified:
const
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.
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.