C++ 使用STL填充向量<;T>;从地图<;T、 Z>';钥匙 map m=。。。; 向量v; v、 储备(m.size); for(map::iterator it=m.begin();it!=m.end();++it) { v、 向后推(它->第一个); }

C++ 使用STL填充向量<;T>;从地图<;T、 Z>';钥匙 map m=。。。; 向量v; v、 储备(m.size); for(map::iterator it=m.begin();it!=m.end();++it) { v、 向后推(它->第一个); },c++,stl,C++,Stl,是否有更好的使用STL函数的单线版本 编辑:不使用c++11便携式: map<T,Z> m= ...; vector<T> v; v.reserve(m.size); for(map<T,Z>::iterator it=m.begin();it!=m.end();++it) { v.push_back(it->first); } 如果可以使用C++11,则可以使用lambda,它可以使选择代码保持在使用位置附近: template <typen

是否有更好的使用STL函数的单线版本

编辑:不使用c++11便携式:

map<T,Z> m= ...;
vector<T> v;
v.reserve(m.size);
for(map<T,Z>::iterator it=m.begin();it!=m.end();++it)
{
 v.push_back(it->first);
}
如果可以使用C++11,则可以使用lambda,它可以使选择代码保持在使用位置附近:

template <typename F, typename S>
F SelectKey()(const std::pair<const F, S> &x) { return x.first; }

std::transform(m.cbegin(), m.cend(), std::back_inserter(v), SelectKey);

在C++11中,可以使用lambda表达式:

for(const auto &x : m) {
  v.push_back(x.first);
}
typedef std::mapmap\t;
地图;
std::vectorv;
std::for_each(map.begin()、map.end()、[&v](map_t::value_type const&it)
{
v、 向后推(首先推);
});

在C++11之前,您可以使用转换和自定义函数结构:

typedef std::map< std::string, std::string > map_t;
map_t map;
std::vector< std::string > v;

std::for_each(map.begin(), map.end(), [&v](map_t::value_type const& it)
        {
            v.push_back(it.first);
        });
在C++11之后,您可以使用lambdas:

transform(m.begin(), m.end(), back_inserter(v), mem_fn(&map<T,Z>::value_type::first));
transform(m.begin(),m.end(),back_inserter(v),[](const-map::value_-type&x){return x.first;});

您可以按照以下方式进行操作:

transform(m.begin(), m.end(), back_inserter(v), [](const map<T,Z>::value_type& x) {return x.first;});
其中FUNCTOR取决于STL或库和编译器的版本

C++11(lambda)


C++03(不是C++11)像其他人所描述的那样使用函子对象。

Overkill?无论如何,您键入的代码行并不是太多。@Als:按照这种逻辑,std::algorithm的大部分都是无用的。@Mahesh-我在考虑一些反向插入器魔法,或者一些您可以使用某种转换迭代器的东西,但我忘了标准库中是否有。Boost有一个。然后您可以直接从一对迭代器构造
v
。不确定你最终会不会减少打字,但是:-你真的是指STL,或者你是指C++标准库?那么它实际上是一行。您的
操作符()
应该是
常量。在TR1中,这可以通过
std::bind(&map::value_type::first,_1)
实现。不应该模板化结构,而应该模板化
操作符()。如果你真的想模板化这个结构,你应该在创建它的时候提供参数:
SelectKey()
。所有的注释都很好。我在回答中提到了lambda,但我一定是无意中删除了它。@John您也可以传递一个函数,但您仍然必须首先定义该函数(因为
是一个变量),所以您也可以只使用一个至少可以在本地定义的函子。在C++11之前的版本中,您不能使用
绑定
。如果你依赖于非std扩展或boost,那么就这么说。@Christian:没错,有一点需要注意,C++11之前的版本你可以使用
std::tr1::bind
@ildjarn是的,但是他应该这么说,而不是假装它是标准的。唉,我已经使用tr1很久了,我忘了它不是C++03的一部分。在C++03中,您可以使用mem_fn或bind1st,不是吗?当我有时间的时候,我会看看我是否能找到C++03文档并修正我的答案。@Ayjay它不适用于
std::mem\fn
,因为
std::pair
first
成员不是一个函数,而是一个变量。现在我想知道它是否能与
tr1::bind
一起工作?
template <class K, class V>
struct key_selector : std::unary_function<const std::pair<K, V>&, const K&>
{
    const K& operator()(const std::pair<K, V>& element) const
    {
        return element.first;
    }
};

transform(m.begin(), m.end(), back_inserter(v), key_selector<T,Z>());
transform(m.begin(), m.end(), back_inserter(v), mem_fn(&map<T,Z>::value_type::first));
transform(m.begin(), m.end(), back_inserter(v), [](const map<T,Z>::value_type& x) {return x.first;});
std::transform(m.begin(), m.end(), std::back_inserter(v), FUNCTOR);
std::transform(m.begin(), m.end(), std::back_inserter(v), [](map<T,Z>::const_reference a) { return a.first; });
std::transform(m.begin(), m.end(), std::back_inserter(v), &std::get<0>);
std::transform(m.begin(), m.end(), std::back_inserter(v), select1st);