为什么我不能在 std::transform 中使用 std::get<0>?
Why can't I use std::get<0> in std::transform?
在尝试编译以下代码时,该代码会将map
的密钥复制到vector
:
map<string, string> mss;
vector<string> vs;
transform(mss.begin(), mss.end(), back_inserter(vs), get<0>);
VS2013无法区分哪个get
,但这种更简单的用法工作得很好:
vs.push_back(get<0>(*mss.begin()));
指定get<0, string, string>
没有帮助。我错过了什么?
有许多重载 std::get
,此外,每个重载本身都是一个函数模板,因此编译器无法在您请求其中一个地址的调用站点上判断您想要哪一个。如果你坚持使用std::get
,你需要使用static_cast
:
transform(mss.begin(), mss.end(), back_inserter(vs),
static_cast<const map<string, string>::key_type&
(*)(map<string, string>::value_type&)>(std::get<0>)
);
只要 static_cast
中的类型与作为参数给出的可能函数模板专用化的声明匹配,它就会起作用。此外,您不必尝试显式指定函数模板的模板参数,如get<0, string, string>
等 - 这就是模板参数推断机制的用途。不仅语法丑陋,而且将来可能会添加其他重载来破坏您的编译。
一个更好的选择是使用 lambda 表达式:
transform(mss.begin(), mss.end(), back_inserter(vs),
[](map<string, string>::value_type& p){ return p.first; });
或通用 lambda 表达式 (C++14(:
transform(mss.begin(), mss.end(), back_inserter(vs),
[](auto& p){ return p.first; }); // or `return std::get<0>(p);`
或将其参数绑定到指向数据成员或成员函数的给定指针的std::mem_fn
:
#include <functional>
transform(mss.begin(), mss.end(), back_inserter(vs),
mem_fn(&map<string, string>::value_type::first));
存储在 map 中的对的第一个成员是 const 限定的。所以从技术上讲,你需要
get<0, const string, string>
但这并不能将候选列表限制为一个明确的重载,因为get
至少有两个版本可用:常量引用参数和非常量引用参数。
您可以使用演员表选择一个
const string &(*g)(const pair<const string, string> &) =
get<0, const string, string>;
或
typedef map<string, string> Map;
const Map::key_type &(*g)(const Map::value_type &) =
get<0, const Map::key_type, Map::mapped_type>;
然后做
transform(mss.begin(), mss.end(), back_inserter(vs), g);
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 错误:调用"std::vector<:vector<int>>::p ush_back(std::vector<std::__cxx11::basic_string<
- C 建造者Clang STD :: Sill,找不到超载的操作员&lt;
- 为什么STD :: MAP需要操作员&lt;以及我如何写一个
- std::vector::reserve(未知m),我知道m<<;N(通常)并且知道N
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- C++运算符<<调用::ostream而不是std::osttream
- 是std :: set&lt; std :: future&gt;不可能存在
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- BOOST ::变体无法解决运算符&lt;&lt;对于STD :: Ostream
- C++重载<<具有typedef'd std::vector
- 以x的倍数填充前导零,使用std::cout<<std::十六进制
- 错误:没有匹配'运算符<<"在'std::cout
- std::pair的默认构造函数<>将基本类型(int等)设置为零
- std::ostream&operator< & lt; (std:: ostream&压力,压力& &;val)
- 将std::endl传递给std::operator<<
- std::映射<>或std::vector<>在处理大型标志集时
- 重载& lt; & lt;使用命名空间std