接收任何标准映射的函数模板
Function template receiving any standard map
我正在编写一个函数,应该接收(std::map
, std::multimap
, std::unordered_map
或std::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::map
、std::multimap
接收4个模板参数,std::unordered_map
、std::unordered_multimap
接收5个模板参数。这意味着我不能用模板模板参数解决这个问题。是否有任何方法来解决这个约束,所有地图必须有KeyType = ValeType = Coord
?我不想在调用filter
时显式地指定参数类型。
你标记了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;
}
}
}
写你自己的type trait:
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
/Value
是Coord
:
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_type
来缩短它,验证它们都存在并且与COORD
相同:
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
{ };
尽管这些模板类接受不同数量的参数,但它们都有默认值,因此都可以只用两个实例化。因此,您可以只使用可变参数模板,然后任何不能用两个参数实例化的东西都会导致编译器错误:
template<template <class...> class Map, typename Coord>
相关文章:
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 将重载的成员函数传递给函数模板
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 如何创建对象函数指针C++映射?
- 具有常量引用参数的函数模板专用化
- std::span<const T> 作为函数模板中的参数
- 如何编写一个完美的缩写函数模板?
- 仅在函数模板中为那些定义了函数的类型执行函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 以下代码中的函数模板有什么问题?
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 将显式实例化的函数模板与转换匹配
- 使用定义函数模板别名
- 函数模板返回类型
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- C++ std::functional 中的可变参数函数模板
- 在函数模板中将一个类型名映射到另一个类型名
- 为对象指针映射编写函数模板时出现问题
- 接收任何标准映射的函数模板