首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >接收任何标准映射的函数模板

接收任何标准映射的函数模板
EN

Stack Overflow用户
提问于 2015-05-21 21:06:06
回答 3查看 499关注 0票数 9

我正在写一个函数,它应该接收(std::mapstd::multimapstd::unordered_mapstd::unordered_multimap)中的一个。我的代码如下:

代码语言:javascript
复制
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的调用中显式指定参数类型。

EN

回答 3

Stack Overflow用户

发布于 2015-05-21 21:13:33

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

代码语言:javascript
复制
template <typename M, typename COORD>
struct is_map_of_coord : std::false_type { };

然后将其专门用于5个地图:

代码语言:javascript
复制
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

代码语言:javascript
复制
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_typemapped_type,验证这两个都存在并且与COORD相同,就可以缩短这段时间

代码语言:javascript
复制
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
{ };
票数 4
EN

Stack Overflow用户

发布于 2015-05-21 21:20:43

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

代码语言:javascript
复制
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;
        }   
    }   

}   
票数 4
EN

Stack Overflow用户

发布于 2015-05-21 21:12:56

尽管这些模板类接受不同数量的参数,但它们都有默认值,因此只需两个参数就可以全部实例化。因此,你可以只使用可变模板,那么任何不能用两个参数实例化的东西都会导致编译器错误:

代码语言:javascript
复制
template<template <class...> class Map, typename Coord>
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30374670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档