简体   繁体   English

为什么我不能在std :: transform中使用std :: get <0>?

[英]Why can't I use std::get<0> in std::transform?

In trying to compile the following code which would copy a map s keys to a vector : 在尝试编译以下代码时,会将map s键复制到vector

map<string, string> mss;
vector<string> vs;

transform(mss.begin(), mss.end(), back_inserter(vs), get<0>);

VS2013 can't distinguish which get is intended but this simpler usage works just fine: VS2013无法区分哪个get是有意的,但这个更简单的用法可以正常工作:

vs.push_back(get<0>(*mss.begin()));

Specifying get<0, string, string> didn't help. 指定get<0, string, string>没有帮助。 What am I missing? 我错过了什么?

There are many overloads of std::get , where, in addition, each is a function template itself, therefore the compiler can't tell which one you want at the call site where you request for the address of one of them. std::get有很多重载,其中每个都是一个函数模板本身,因此编译器无法在你请求其中一个地址的调用站点分辨出你想要的那个。 If you insist on using std::get , you'd need to use static_cast : 如果你坚持使用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>)
                     );

Which will work as long as the type in static_cast matches the declaration of a possible function template's specialization given as the argument. 只要static_cast中的类型与作为参数给出的可能的函数模板的特化的声明匹配,这将起作用。 Also, you shoudn't try to explicitly specify the template arguments of function templates like get<0, string, string> etc. - this is what the template argument deduction mechanism is for. 此外,您不应尝试显式指定函数模板的模板参数,如get<0, string, string>等。这就是模板参数推导机制的用途。 Not only is the syntax ugly, but there can be other overloads added in the future breaking your compilation. 语法不仅难看,而且将来可能会增加其他重载,从而破坏您的编译。

A much better alternative is to use a lambda expression : 一个更好的选择是使用lambda表达式

transform(mss.begin(), mss.end(), back_inserter(vs),
          [](map<string, string>::value_type& p){ return p.first; });

or a generic lambda expression (C++14): 一般的lambda表达式 (C ++ 14):

transform(mss.begin(), mss.end(), back_inserter(vs),
          [](auto& p){ return p.first; }); // or `return std::get<0>(p);`

or std::mem_fn which binds its argument to a given pointer to a data member or a member function: 或者std::mem_fn ,它将其参数绑定到指向数据成员或成员函数的给定指针:

#include <functional>

transform(mss.begin(), mss.end(), back_inserter(vs),
          mem_fn(&map<string, string>::value_type::first));

The first member of the pair stored in map is const-qualified. 存储在map中的对的第一个成员是const限定的。 So technically you need 所以技术上你需要

get<0, const string, string>

But that does not limit the list of candidates to one unambiguous overload, since get is available in at least two versions: for const reference argument and for non-const reference argument. 但是这并不会将候选列表限制为一个明确的重载,因为get至少有两个版本:const参数参数和非const参考参数。

You can choose one by using a cast 您可以使用演员表选择一个

const string &(*g)(const pair<const string, string> &) = 
  get<0, const string, string>; 

or 要么

typedef map<string, string> Map;

const Map::key_type &(*g)(const Map::value_type &) = 
  get<0, const Map::key_type, Map::mapped_type>; 

and then do 然后呢

transform(mss.begin(), mss.end(), back_inserter(vs), g);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以使用std :: generate来获取std :: array的向量 <T, 2> ? - Can I use std::generate to get a vector of std::array<T, 2>? 为什么我不能将std :: function用作std :: set或std :: unordered_set值类型? - Why can't I use std::function as a std::set or std::unordered_set value type? 为什么我不能使用std :: begin / std :: end和int(* p)[3]而我可以使用int(&p)[3]? - Why can't I use std::begin/std::end with int(*p)[3] while I can with int(&p)[3]? 为什么我不能得到std :: function <std::vector<T> :: iterator&gt;绑定到返回该类型的lambda? - Why can't I get std::function<std::vector<T>::iterator> to bind to lambda returning that type? 为什么我不能使用auto与std :: thread? - Why can't I use auto with std::thread? 为什么我不能使用operator &lt;on&#39;std :: deque&#39;? - Why can't I use operator< on 'std::deque'? 为什么我不能使用 lambda 按值对 std::map 进行排序 - Why can't I use lambda to sort std::map by value 为什么我不能在std :: future参数中使用reference - Why can't I use reference in std::future parameters 为什么我不能将gtest ValuesIn生成器与std :: map一起使用? - Why can't I use the gtest ValuesIn generator with a std::map? 为什么我不能将 std::iterator&lt;&gt;::reference 与模板一起使用? - Why can't I use std::iterator<>::reference with templates?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM