tags:

views:

483

answers:

1

I had encountered strange problem while construct a unordeed_set<tuple<int,int>>. I had tried VC++8, gcc3.2, gcc4.3, all have the same result. I have no idea what's wrong with the code, following is my code:

#include <boost/unordered_set.hpp>
#include <boost/tuple/tuple.hpp>
// For unordered container, the declaration of operator==
#include <boost/tuple/tuple_comparison.hpp>

using namespace std ;
using namespace boost ;

// define of the hash_value funciton for tuple<int, int>
size_t hash_value(tuple<int, int> const& t) {
    return get<0>(t) * 10 + get<1>(t) ;
}

int main () {
    unordered_set<tuple<int, int>> s ;
    tuple<int, int> t ;
    s.insert(t) ;
}

Here is the compile error message:

1>c:\libs\boost_1_37_0\boost\functional\hash\extensions.hpp(72) : error C2665: 'boost::hash_value' : none of the 16 overloads could convert all the argument types
1>        c:\libs\boost_1_37_0\boost\functional\hash\hash.hpp(33): could be 'size_t boost::hash_value(bool)'
1>        c:\libs\boost_1_37_0\boost\functional\hash\hash.hpp(34): or       'size_t boost::hash_value(char)'
1>        c:\libs\boost_1_37_0\boost\functional\hash\hash.hpp(35): or       'size_t boost::hash_value(unsigned char)'
....

It seems the compiler can not see the definition of hash_value(tuple<int, int>). But if I replace the tuple<int, int> to other data type like struct F{int a, b;} and it works. That's really strange. Do I miss anything? Thank you very much.

+4  A: 

Put the hash function in namespace boost.

#include <boost/unordered_set.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>

using namespace std;
using namespace boost;

namespace boost {
    size_t hash_value(tuple<int, int> const & t) {
        return get<0>(t) * 10 + get<1>(t) ;
    }
}

int main () {
    unordered_set< tuple<int, int> > s ;
    tuple<int, int> t ;
    s.insert(t) ;
}
sharth
For more information, read here: http://www.boost.org/doc/libs/1_37_0/doc/html/hash/custom.html
GMan