如何制作一个接受地图或unordered_map的函数
How can I make a function that takes either a map or an unordered_map?
我正在实现一些基于模板的序列化。我实现了std::map
的模板化功能,但现在我使用的是std::unordered_map
。我宁愿不复制和粘贴整个函数,而只是更改参数类型。有没有办法制作一个只需要地图或无序地图的模板?
template <typename MAP>
void generic_foo(MAP& map)
{
// generic implementation of your function
// that works with unordered_map and map
using K = typename MAP::key_type;
using T = typename MAP::mapped_type;
}
// matches any possible implementation of std::unorderd_map
template <class Key,
class T,
class Hash,
class Pred,
class Alloc>
void foo(std::unordered_map<Key, T, Hash, Pred, Alloc>& m)
{
// signature matched! forward to your implementation
generic_foo(m);
}
// matches any possible implementation of std::map
template <class Key,
class T,
class Compare,
class Alloc>
void foo(std::map<Key, T, Compare, Alloc>& m)
{
// signature matched! forward to your implementation
generic_foo(m);
}
现场演示
只需将函数重载为非模板化函数,一个重载采用std::map
,另一个重载取std::unordered_map
。 让这两个函数调用一个隐藏的template
,该接受任何内容,但只能由它们调用。 一种方法是将其隐藏在匿名namespace
中。
具有 C++20 个概念
要支持特定的std::map
和std::unordered_map
:
template<typename T> struct is_unordered_map
: public std::false_type {};
template<typename... Args>
struct is_unordered_map<std::unordered_map<Args...>>
: public std::true_type {};
template<typename T> struct is_map
: public std::false_type {};
template<typename... Args>
struct is_map<std::map<Args...>>
: public std::true_type {};
template<typename C>
concept UnorderedMap = is_unordered_map<C>::value;
template<typename C>
concept Map = is_map<C>::value;
template<typename C>
concept MappingContainer =
Map<C> || UnorderedMap<C>;
void foo(const MappingContainer auto& m) { ... }
代码:https://godbolt.org/z/MrsaGn
<小时 />若要支持任何充当映射类型的类型,请执行以下操作:
template<typename C>
concept MappingContainer = requires(C c) {
typename C::key_type;
typename C::mapped_type;
typename C::value_type;
typename C::iterator;
requires std::same_as<decltype(c.begin()), typename C::iterator>;
requires std::same_as<decltype(c.end()), typename C::iterator>;
requires std::same_as<
typename C::value_type,
std::iter_value_t<typename C::iterator>
>;
requires std::same_as<
typename C::value_type,
std::pair<const typename C::key_type, typename C::mapped_type>
>;
};
void foo(const MappingContainer auto& m) { ... }
代码:https://godbolt.org/z/jPfMhT
#include<type_traits>
template<typename T>
void foo(T t){
static_assert(std::is_same<T, std::map</*some_type*/>::value
|| std::is_same<T, std::unordered_map</*some_type*/>::value,
"Foo can only get std::map or std::unordered_map.");
}
下面是
一个从std::map
或std::unordered_map
中提取键/值的示例
template <typename M>
std::unordered_set<typename M::key_type> GetMapKeys(const M& a_map) {
std::unordered_set<typename M::key_type> keys;
for (auto const& e : a_map) {
keys.emplace(e.first);
}
return keys;
}
template <typename M>
std::vector<typename M::mapped_type> GetMapValues(const M& a_map) {
std::vector<typename M::mapped_type> values;
values.reserve(a_map.size());
for (auto const& e : a_map) {
values.push_back(e.second);
}
return values;
}
相关文章:
- 为什么不;名字在地图上是按顺序排列的吗
- 基于多个条件处理地图中的所有元素
- 在C++中将矢量转换为嵌套地图
- 替换基于地图的所有引用
- 如何区分地图中的 0 和 false?
- 地图计数确实很重要,或者只是检查是否存在
- 如何从地图中删除矢量对象
- 是否有任何C++功能可以对地图进行排序?
- 如何使用 std::variant 打印地图键/值?
- 从矢量或地图中删除共享指针
- 在 c++ 中,有一种方法可以创建一个包含地图作为值的树状地图?
- 无限嵌套具有变体的地图
- C++一会儿循环读到地图上 2 行?
- 如何在cpp中使用地图显示给定日期范围内(在下面的问题中)的费率?
- 如何检查变量是否是C++中的地图?
- 如何使地图按值C++排序
- 修改地图内矢量中的值
- 为什么我在地图中搜索STL时差很大?
- 我正在尝试按降序对地图进行排序,但没有得到预期的结果?
- 如何包装(撰写)增强 hana 地图并访问括号运算符(运算符 [])?