Now that the C++20 ranges implementation is actually here and released under GCC 10.2, I would like to know how to convert a ranges view back to an actual container, like a vector. I've found this question ( Range view to std::vector ) that asked the same thing for the pre-release version but I would like to know if since its been released, have there been any new methods made to convert from a view to a container? Or is that single answer on that question still the best solution?
I know this says C++20, but going forward the answer is C++23's std::ranges::to. It is a function template that has various ways to use it, including pipe or function (std::ranges::to<std::vector>(intsView)
or intsView | std::ranges::to<std::vector>()
), and implicit or explicit value-type (std::ranges::to<std::set>(intsView)
or std::ranges::to<std::set<int>>(intView)
). It also supports allocators. We have an implementation of roughly this in our codebase and use it all the time. There are so many cases that you want to collect a bunch of values together into a container, and std::ranges::to
provides a great, concise, expressive API for doing exactly that. It even supports maps:
// Project out the "foo" field of this->m_database
auto map = std::ranges::to<absl::flat_hash_map>(
this->m_database | std::views::transform([&](const auto& row) {
return std::pair{row.first, row.second.foo};
})
);