c++boostboost-range

Construct new container from transformed range


In my code, I frequently have to create a new container from a previously transformed range. So far I have used a combination of boost::adaptors::transformed and boost::copy_range to do the job, thinking that the container's constructor should be able to preallocate the necessary memory. Unfortunately, I have noticed that boost::adaptors::transform returns a SinglePassRange and I'm not sure if the size of the range can be determined in constant time.

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); 
    }));

So my question is: What is the best generic way to construct a new container from a transformed range ideally as one expression?


Solution

  • You can use boost::adaptors::transformed. The docs state that the input range MUST at least be SinlgePassRange, but also says:

    SO if the input range is random-access the output range will be, too. This removes your worry.