FPGalero FPGalero - 1 month ago 12
C++ Question

Using typedef with a constructor parameter

Following my previous question, Defining a class member according to the class template, I've realized that the default bucket count of an

unordered_map
is too low for my purposes.

I have a class template
Base
that will use a map or an unordered map, depending on the template parameters:

template<class A, class B>
class Base {
template<class T1, class T2>
struct MapType { typedef boost:unordered_map<...> MType; };
template<class T2>
struct MapType<std::string, T2> { typedef std::map<...> MType; };

typedef typename MapType<...>::MType Map;

Map mMap;
};


I would like to change the default size of
Map
in case it is the latter type by using its consturctor (first parameter defines the size) or by using the unordered map
rehash
function.

My only idea so far is to use the
Base
class constructor to check (
dynamic_cast
?) whether my
mMap
is a map or an unordered map followed by the use of the
rehash
function.

The only limitation is that this code is being used in hundreds of places which mustn't change (can't polymorph my base class).

Answer

Since MapType is already a trait class for abstracting some aspect of Map (its type), you can extend it to abstract another aspect (the construction):

template<class A, class B> 
class Base {
    template<class T1, class T2>
    struct MapType {
      typedef boost:unordered_map<...> MType;
      static MType create() { return MType(BUCKET_SIZE); }
    };

    template<class T2>
    struct MapType<std::string, T2> {
      typedef std::map<...> MType;
      static MType create() { return MType(); }
    };

    typedef typename MapType<...>::MType Map;

    Map mMap;

    Base() : mMap(MapType<...>::create()) {}
}

Of course, you can pass in some parameters into create (and ignore some/all of them in one or the other case), or have the create-like function operate on an existing map instead of returning a new one, based on your real use-case needs.

Comments