std::unordered_map with std::vector<char> key

Hello, how exactly do I add a hash function so that std::vector<char> can be used as keys in std::unordered_map, seeing as it already works fine for std::string?
Thank you.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <vector>
#include <unordered_map>
#include <boost/functional/hash.hpp>

template < typename SEQUENCE > struct seq_hash
{
    std::size_t operator() ( const SEQUENCE& seq ) const
    {
        std::size_t hash = 0 ;
        boost::hash_range( hash, seq.begin(), seq.end() ) ;
        return hash ;
    }
};

template < typename SEQUENCE, typename T >
using sequence_to_data_map = std::unordered_map< SEQUENCE, T, seq_hash<SEQUENCE> > ;

int main()
{
    sequence_to_data_map< std::vector<char>, int > hash_table ;

    hash_table[ { 'a', 'b', 'c', 'd', 'e', 'f' } ] = 100 ;
}
Thank you for that code, but isn't there a pure C++11 solution, or something that can be reused from the STL?
Or, if you can afford to construct a string each time the hash is computed:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <list>
#include <unordered_map>
#include <string>

template < typename CHAR_SEQUENCE > struct char_seq_hash
{
    std::size_t operator() ( const CHAR_SEQUENCE& seq ) const
    { return std::hash<std::string>() ( std::string( seq.begin(), seq.end() ) ) ; }
};

int main()
{
    std::unordered_map< std::list<char>, int,
                        char_seq_hash< std::list<char> > > hash_table ;

    hash_table[ { 'a', 'b', 'c', 'd', 'e', 'f' } ] = 100 ;
}
I guess that's pretty much what I wanted, thanks JLBorges!
Would you consider it bad practice to specialize std::hash()? Like so:

1
2
3
4
5
6
7
8
9
10
11
12
#include <cstddef>
#include <functional>
#include <string>
#include <vector>

template <>
struct std::hash<std::vector<char>> {
    std::size_t operator() (const std::vector<char> &vc) const
    {
        return std::hash<std::string>() (std::string(vc.cbegin(), vc.cend()));
    }
};

> Would you consider it bad practice to specialize std::hash()? Like so:

This is what the IS says:
The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.


Clearly, a specialization
namespace std { template<> std::hash< my_own_type > { /* ... */ }; }
is permitted.

But it is not clear to me if 'user-defined type' referred to above includes types like std::vector<char> or these would be treated as 'library defined types'

I avoid adding anything to the namespace std if I can possibly get the functionality I need without doing it; but that's just me, I suppose.
Topic archived. No new replies allowed.