为什么我不能使用std :: get< 0>在std :: transform中吗? [英] Why can't I use std::get<0> in std::transform?

查看:196
本文介绍了为什么我不能使用std :: get< 0>在std :: transform中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在尝试编译以下代码时,这些代码会将map s的密钥复制到vector:

In trying to compile the following code which would copy a maps keys to a vector:

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

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

VS2013无法区分要使用哪个get,但是这种更简单的用法可以正常工作:

VS2013 can't distinguish which get is intended but this simpler usage works just fine:

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

指定get<0, string, string>并没有帮助.我想念什么?

Specifying get<0, string, string> didn't help. What am I missing?

推荐答案

,此外,每个模板本身都是一个功能模板,因此编译器无法告诉您在呼叫站点上想要哪个地址来请求其中之一的地址.如果您坚持使用std::get,则需要使用static_cast:

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. If you insist on using std::get, you'd need to use 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>等)的模板参数.这就是模板参数推导机制的目的.语法不仅丑陋,而且将来还会增加其他重载,从而破坏您的编译.

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. 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. Not only is the syntax ugly, but there can be other overloads added in the future breaking your compilation.

更好的替代方法是使用 lambda表达式:

A much better alternative is to use a lambda expression:

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

通用lambda表达式(C ++ 14):

or a generic lambda expression (C++14):

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

std::mem_fn ,将其参数绑定到指向数据成员的给定指针,或者成员函数:

or std::mem_fn which binds its argument to a given pointer to a data member or a member function:

#include <functional>

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

这篇关于为什么我不能使用std :: get&lt; 0&gt;在std :: transform中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆