std::map<K,V>
实现std::function<V(K)>
类型的部分函数。
我正在尝试实现一个将map2fun()
转换为std::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];
};
}
我的问题是:
答案 0 :(得分:4)
STL for C ++ 11中是否有类似的功能?
不,据我所知。
但std::map
本身就是&#34; STL for C ++ 11&#34;中可用的类似功能。 (以及C ++ 98),恕我直言。
如果没有,我怎样才能用C ++ 11实现它?
通过示例
为代码添加一些typename
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开始,简化如下
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
),这给出了一个非常难看的错误消息(不是简单的&#34) ; map2fun()未实现)。
如果C
容器定义mapped_type
类型,则可以使用SFINAE避免此问题,仅启用此功能(通过示例);我的意思是
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;
}