接收任何标准地图的功能模板

时间:2015-05-21 13:06:06

标签: c++ templates c++11

我正在编写一个应该收到(std::mapstd::multimapstd::unordered_mapstd::unordered_multimap之一的函数。我的代码如下:

template<template <class, class> class Map, typename Coord>
    inline typename std::enable_if<std::is_arithmetic<Coord>::value>::type 
    filter(Map<Coord, Coord>& map, Coord step = 2) {
            for (auto it = std::begin(map); it != std::end(map);) {
                if (it->second - it->first <= step){
                    it = map.erase(it);
                }
                else
                    ++it;
            }
        }

模板模板参数Map不会针对所有类型的地图进行推广。 std::mapstd::multimap会收到四个模板参数,std::unordered_mapstd::unordered_multimap会收到五个模板参数。这意味着我无法使用模板模板参数解决问题。有没有办法解决这个问题,所有地图必须有KeyType = ValeType = Coord的约束?我不想在调用filter时明确指定参数类型。

3 个答案:

答案 0 :(得分:4)

只需编写自己的类型特征:

template <typename M, typename COORD>
struct is_map_of_coord : std::false_type { };

然后你专门研究5张地图:

template <typename COORD, typename C, typename A>
struct is_map_of_coord<std::map<COORD, COORD, C, A>, COORD>
: std::true_type { };

template <typename COORD, typename H, typename K, typename A>
struct is_map_of_coord<std::unordered_map<COORD, COORD, H, K, A>, COORD>
: std::true_type { };

etc.

只要map / Key ValueCoord,就可以接受任何template <typename Map, typename Coord = int> inline typename std::enable_if< std::is_arithmetic<Coord>::value && is_map_of_coord<Map, Coord>::value >::type filter(Map& map, Coord step = 2) { /* body */ } ,无论其分配器,比较器,哈希函数等如何:

key_type

或者您可以通过假设所有地图都有mapped_typeCOORD来缩短它,请验证这些地图是否存在且与template <typename...> using void_t = void; template <typename M, typename COORD, typename = void> struct is_map_of_coord : std::false_type { }; template <typename M, typename COORD> struct is_map_of<M, K, void_t< std::enable_if_t<std::is_same<typename M::key_type, COORD>::value>, std::enable_if_t<std::is_same<typename M::mapped_type, COORD>::value> > > : std::true_type { }; 相同:

defaults delete com.apple.dt.Xcode
rm -rf $HOME/Library/Application Support/Developer/Shared/Xcode
rm -rf $HOME/Library/Saved\ Application\ State/com.apple.dt.Xcode.savedState
rm -rf $HOME/Library/Preferences/com.apple.dt.Xcode.*

答案 1 :(得分:4)

您标记了c ++ 11,因此我尝试使用可变参数模板参数:

template<template <class ... > class Map, typename Coord, typename ... MapParms >
inline typename std::enable_if<std::is_arithmetic<Coord>::value>::type
filter(Map<Coord, Coord, MapParms... >& map, Coord step = 2)  
{   
    for (auto it = std::begin(map); it != std::end(map);) 
    {   
        if (it->second - it->first <= step)
        {   
            it = diagram.erase(it);
        }   
        else
        {   
            ++it;
        }   
    }   

}   

答案 2 :(得分:1)

虽然这些模板类使用不同数量的参数,但它们具有默认值,因此只能使用两个参数进行实例化。因此,你可以使用一个可变参数模板,然后任何不能用两个参数实例化的东西都会导致编译器错误:

template<template <class...> class Map, typename Coord>