I'm trying to make a class that takes a map as a template parameter. In particular it should be able to take std::map and boost::ptr_map. Currently I'm trying this:
template <template<typename, typename> class MAP, typename KEYTYPE, typename DATATYPE>
class RestrictedMapBase
{
/* bunch of methods ... */
}
This class is being inherited by two other classes, one for std::map and one for boost::ptr_map.
template <typename KEYTYPE, typename DATATYPE>
class RestrictedMap: public RestrictedMapBase<std::map, KEYTYPE, DATATYPE>
{
/* Bunch of methods ... */
};
template <typename KEYTYPE, typename DATATYPE>
class RestrictedPointerMap: public RestrictedMapBase<boost::ptr_map, KEYTYPE, DATATYPE>
{
/* Bunch of methods ... */
};
But on compilation I get these errors:
RestrictedMap.h(166) : error C3201: the template parameter list for class template 'std::map' does not match the template parameter list for template parameter 'MAP' RestrictedMap.h(183) : see reference to class template instantiation 'STLUtils::RestrictedMap' being compiled
RestrictedMap.h(186) : error C3201: the template parameter list for class template 'boost::ptr_map' does not match the template parameter list for template parameter 'MAP' RestrictedMap.h(203) : see reference to class template instantiation 'STLUtils::RestrictedPointerMap' being compiled
Can anybody point me in the right direction of what I'm doing wrong? Thanks.
std::map expects a template parameter to define what it is a map of. See below:
template <typename KEYTYPE, typename DATATYPE>
class RestrictedMap: public RestrictedMapBase<std::map<KEYTYPE, DATATYPE>, KEYTYPE, DATATYPE>
{
/* Bunch of methods ... */
};
Your base class template parameters KEYTYPE
and DATATYPE
then become redundant. You can replace those with the typedefs provided in std::map's class:
std::map<_Kty, _Ty>::key_type; // This is the same as KEYTYPE
std::map<_Kty, _Ty>::mapped_type; // This is the same as DATATYPE
I would re-write your class something like this (I haven't tested this):
template <typename Map>
class RestrictedMap
{
public: // Typedefs
typedef typename Map::key_type KeyType;
typedef typename Map::mapped_type MapType;
public: // Methods
// TODO: Write your methods here.
void Add(const KeyType &key, const MapType &map);
private: // Members
Map m_map;
};
Then you could choose your map like this (again un-tested):
typedef RestrictedMap<std::map<int, int>> StlMap; // TODO: Change your map's key and data type
typedef RestrictedMap<boost::ptr_map<int, int>> BoostMap; // TODO: Change your map's key and data type
Full example available here - http://ideone.com/U3AkV
Class template std::map
have 4 arguments:
template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
class map
Thus it can not be pass via template<typename, typename>
just like you can not assign a pointer to a 3-argument function to a pointer to 2-argument function.
The solution is to pass the exact type to use to RestrictedMapBase
:
template <typename MAP>
class RestrictedMapBase
{
typedef typename MAP::key_type KEYTYPE;
typedef typename MAP::mapped_type DATATYPE;
};
Your initial design also limits users of your class because they can not specify a compare function for keys (or a hash function if they want to use hash tables) and an allocator.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.