使用不同类型的容器的迭代器范围初始化容器

时间:2015-09-03 13:40:32

标签: c++ c++11 stl

假设我们有std::set<int>,我们想要创建一个std::vector<int>,其中包含该集合中的所有值:

std::set<int> set;
std::vector<int> vec( set.begin(), set.end() );

这很简单而优雅。但是,假设我有一个std::map<std::string,int>,我想将所有值复制到std::vector<int>。不幸的是,没有构造函数,它接受迭代器和转换器函数的范围。为什么没有提供这样的构造函数?是否有另一种简单而优雅的方法来初始化一个具有不同类型值的容器?

4 个答案:

答案 0 :(得分:6)

使用transform iterators:

#include <boost/iterator/transform_iterator.hpp>
#include <vector>
#include <map>

int main() {
    std::map<int, double> m;
    auto f = [](auto&& pair) { return pair.second; };
    std::vector<double>(boost::make_transform_iterator(m.begin(), f),
                        boost::make_transform_iterator(m.end(), f));
}

或者,使用boost :: adapters:

#include <boost/range/adaptor/map.hpp>
#include <vector>
#include <map>

int main() {
    std::map<int, double> m;
    auto range = boost::adaptors::values(m);
    std::vector<double>(range.begin(), range.end());
}

或与上述相同:

    auto v = boost::copy_range<std::vector<double> >(boost::adaptors::values(m));

请注意,使用vector的范围构造函数比涉及back_inserter的解决方案更有效。

答案 1 :(得分:2)

使用boost::transform_iterator

#include <functional>
#include <boost/iterator/transform_iterator.hpp>

std::map<std::string, int> m{ {"a", 1}, {"b", 2} };
auto second = std::mem_fn(&std::map<std::string, int>::value_type::second);

std::vector<int> vec(boost::make_transform_iterator(std::begin(m), second)
                   , boost::make_transform_iterator(std::end(m), second));

DEMO

答案 2 :(得分:1)

std::map有另一个内存模型,存储值为std::pair。解包这些不是构造函数的工作。您可以在地图对上创建等于地图reservesize的向量iterate内存,以将整数推送到向量的背面。 std::transform减少了这一点。

答案 3 :(得分:0)

我认为你能做的最好的事情就是使用基于范围的循环或for_each函数。