I have a range based on a forward iterator, so the size isn't known before encountering the end iterator. This iterator is used for a transformation with range-v3:
auto src = GetForwardIteratorRange();
auto dest = src | rv::transform([](auto item) { ... }) | r::to<vector>;
If I want to do dest.reserve(100'000)
first, is there a way I can fill this vector later idiomatically with range-v3? Like doing r::to(dest)
(which doesn't work)?
Edit: I'm not even sure
auto src = GetForwardIteratorRange();
auto transform = src | rv::transform([](auto item) { ... });
vector dest;
dest.reserve(100'000);
dest.assign(transform.begin(), transform.end());
would work. The cppreference page on vector::assign sounds as if the implementation can just throw any allocated space away ("The past-the-end iterator is also invalidated.")
I could probably use
boost::ranges::copy(transform, back_inserter(dest));
or
boost::ranges::transform(src, back_inserter(dest), [](auto item) {...});
but I'm wondering if I'm overlooking some range-v3 feature here.
Your
reserve
+assign
code is fine.The reason that it says all iterators are invalidated is because it destroys all the exisiting elements, then fills the empty space with the new elements, which in general might mean an allocation, but in your case won't, if your estimate is good.
ranges::to
accepts a pack of arguments to pass to the constructor besides the iterators, so you could write a wrapper type that reserved space in a vector, then assigned into it.