tags:

views:

226

answers:

3

Hi,

A C++ hash_map has the following template parameters:

template<typename Key, typename T, typename HashCompare, typename Allocator>

How can I specify a Allocator without specifying the HashCompare?

This won't compile :(

hash_map<EntityId, Entity*, , tbb::scalable_allocator>
+8  A: 

The simple answer is that you can't. You cannot skip a template parameter and have it choose the default value for the template. Your only option is to find out what the default is and insert it into your declaration.

JaredPar
While the simple way won't work, there's other ways to still achieve that. See Richard's and my answer.
sbi
+3  A: 

If the has map type has some public typedef for the HashCompare template parameter, you could write a meta function that uses a vanilla hash map type to get the std comparator. Something like this:

template< typename Key, typename T, typename Allocator>
struct hash_map_type {
  typedef typename hash_map<Key,T>::key_compare key_compare;
  typedef mash_map<Key,T,key_compare,Allocator> result_t;
};

typedef hash_map_type<int,string,my_allocator>::result_type my_hash_map;

This, however, depends on something like the above hash_map<Key,T>::key_compare being accessible.

sbi
+1: You're answer is the next logical step from mine...
Richard Corden
+2  A: 

There's one trick you can use which will at least save you having to work out what the default is, but it does require that you know the name of the type as it is defined in hash_map.

The hash_map will probably be declared something like:

class allocator {};
class hash_compare {};

template<typename Key
  , typename T
  , typename HashCompare = hash_compare
  , typename Allocator = allocator>
class hash_map
{
public:
  typedef HashCompare key_compare;
  // ...
};

We cannot leave out the default for the hash, but we can refer to the default using the member typedef:

hash_map<EntityId
  , Entity*
  , hash_map<EntityId,Entity*>::key_compare  // find out the default hasher
  , tbb::scalable_allocator> hm;

If you're going to use the type a lot, then create a typedef:

typedef hash_map<EntityId,Entity*>::key_compare EntityKeyCompare;

hash_map<EntityId
  , Entity*
  , EntityKeyCompare
  , tbb::scalable_allocator> hm;
Richard Corden