从转换范围构造新容器

时间:2018-07-25 07:35:09

标签: c++ boost boost-range

在我的代码中,我经常不得不从先前转换的范围中创建一个新容器。到目前为止,我已经使用boost::adaptors::transformedboost::copy_range的组合来完成这项工作,认为容器的构造函数应该能够预分配必要的内存。不幸的是,我注意到boost::adaptors::transform返回了SinglePassRange,我不确定是否可以在恒定时间内确定范围的大小。

namespace boost {
    template <typename SeqT, typename Range>
    inline SeqT copy_range(const Range& r)
    {
        return SeqT(boost::begin(r), boost::end(r));
    }
}

auto ints = std::vector<int>{...};
auto strings = boost::copy_range<std::vector<std::string>>(
    boost::adaptors::transform(ints, [](auto val) { 
        return std::to_string(val); 
    }));

所以我的问题是:从理想的转换范围作为一个表达式构造一个新容器的最佳通用方法是什么?

2 个答案:

答案 0 :(得分:2)

您可以使用boost :: adaptors :: transformed。文档指出, input 范围必须至少为SinlgePassRange,但还应指出:

  • 返回范围类别:rng的范围类别。
因此,如果输入范围是随机访问的,那么输出范围也将是。这消除了您的烦恼。

答案 1 :(得分:-2)

std::transform是在C ++ 11及更高版本中使用的方法:

std::set<int> ints = {1,2,3,1};
std::vector<std::string> strings;
std::transform(ints.begin(), ints.end(), std::back_inserter(strings), [] (int i) {
    return std::to_string(i)});

使用此方法,您只能将变换应用于给定范围内的每个元素。如果您还想进行一些过滤,则可以使用std::copy_if。我建议研究标题,其中充满了宝石。

编辑:添加了back_inserter