c++ - 如何将 std::map 转换为 std::function?
问题描述
Astd::map<K,V>
实现了type 的部分函数std::function<V(K)>
。
我正在尝试实现一个map2fun()
将 astd::map
转换为std::function
对象的通用函数。
以下不编译:
template<typename M>
function<M::mapped_type(M::key_type)> map2fun(M& m)
{
return [&m](M::key_type k)
{
return m[k];
};
}
我的问题是:
- C++11 的 STL 中是否有类似的功能可用?
- 如果没有,我如何用 C++11 实现它?
解决方案
C++11 的 STL 中是否有类似的功能可用?
不,据我所知。
但它std::map
本身是“在 C++11 的 STL 中可用的类似功能”(以及 C++98),恕我直言。
如果没有,我如何用 C++11 实现它?
例如,将一些typename
's 添加到您的代码中
template <typename M>
std::function<typename M::mapped_type(typename M::key_type)> map2fun (M & m)
{ return [&m](typename M::key_type k) { return m[k]; }; }
但我发现这样更清楚
template <typename K, typename V>
std::function<V(K)> m2f2 (std::map<K, V> & m)
{ return [&m](K k) { return m[k]; }; }
但是,正如 Jarod42 所指出的(谢谢!),这个拦截std::map
只(不是std::unordered_map
,不是类似的(也是自定义的)类型),所以你可以使它更灵活如下
template <template <typename ...> class C, typename K, typename V,
typename ... Ts>
std::function<V(K)> m2f2 (C<K, V, Ts...> & m)
{ return [&m](K k) { return m[k]; }; }
并且,从 C++17 开始,将 con 简化如下
template <template <typename ...> class C, typename K, typename V>
std::function<V(K)> m2f2 (C<K, V> & m)
{ return [&m](K k) { return m[k]; }; }
作为 Jarod42 的指针(再次感谢!),此模板模板版本也可用于其他容器(std::vector
例如),这会给出一个非常丑陋的错误消息(不是简单明了的“map2fun() 未实现”)。
您可以使用 SFINAE 避免此问题,仅在C
容器定义mapped_type
类型时启用该功能(通过示例);我是说
template <template <typename ...> class C, typename K, typename V,
typename ... Ts, typename = typename C<K, V, Ts...>::mapped_type>
std::function<V(K)> m2f2 (C<K, V, Ts...> & m)
{ return [&m](K k) { return m[k]; }; }
但现在我更简单的版本比你原来的更复杂:(。
以下是一个完整的工作双重示例
#include <map>
#include <iostream>
#include <functional>
#include <unordered_map>
template <typename M>
std::function<typename M::mapped_type(typename M::key_type)> m2f1 (M & m)
{ return [&m](typename M::key_type k) { return m[k]; }; }
template <template <typename ...> class C, typename K, typename V,
typename ... Ts, typename = typename C<K, V, Ts...>::mapped_type>
std::function<V(K)> m2f2 (C<K, V, Ts...> & m)
{ return [&m](K k) { return m[k]; }; }
int main ()
{
std::map<int, long> m1 {{0, 1L}, {1, 2L}, {2, 4L}, {3, 8L}};
std::unordered_map<int, long> m2 {{0, 1L}, {1, 2L}, {2, 4L}, {3, 8L}};
auto l1 { m2f1(m1) };
auto l2 { m2f2(m2) };
auto l3 { m2f1(m1) };
auto l4 { m2f2(m2) };
std::cout << l1(2) << std::endl;
std::cout << l2(2) << std::endl;
std::cout << l3(2) << std::endl;
std::cout << l4(2) << std::endl;
}
推荐阅读
- sql - 如何形成主键模式?
- android - Xamarin Android 应用程序在发布模式下崩溃(未找到默认构造函数)
- google-app-engine - AppEngine:404 错误,除了部署服务器上的主页(在本地服务器上工作正常)
- url - TYPO3 预览 URL 配置
- c# - 我的应用程序的结构具有不同的功能
- unix - 如何在 Unix 中从具有固定位置的特定字符串的文件中删除行
- c# - 规范化 HtmlAgilityPack 中的空间
- python - 如何从关联表中查询属性(SQLalchemy)
- apache-spark - 为多个租户触发具有条件过滤逻辑的作业
- c# - HttpWebRequest 获取“底层连接已关闭”