Ranges are coming to C++ with the C++20 standard version.
My question: Will we be able to construct (existing) standard-library containers with any range? And more importantly, with range views?
For example, will this:
#include <vector>
#include <iostream>
#include <ranges>
int main() {
auto sq = [](int x) { return x * x; };
std::vector<int> vec { 3, 4, 5 };
std::vector<int> squares { std::ranges::views::transform(vec, sq) };
for(auto i : squares) { std::cout << i << ' '; }
std::cout << std::endl;
}
be a valid program which prints 9 16 25
?
This compiles with the ranges-v3 library, for what that's worth.
My question: Will we be able to construct (existing) standard-library containers with any range? And more importantly, with range views?
No. The only standard library component that is constructible from an arbitrary range that meets the correct criteria is std::span<T>
.
The direction the standard library will likely go with is the one that range-v3 is also going towards (note that the linked example from range-v3 does compile but warns on a deprecated conversion) - using a helper to do conversions for you:
std::vector<int> squares =
std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;
One of the reasons to not go in the direction of range constructors can be seen from the very example you're using:
std::vector<int> squares { std::ranges::views::transform(vec, sq) };
Consider how different that declaration is from these two:
std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );
v
would necessarily be a vector<transform_view<...>>
containing a single transform_view
, while w
would be a vector<int>
.
Moreover, adding more, carefully constrained container constructors to the standard library isn't going to help third-party container types anyway - while a facility like ranges::to
works perfectly well in all cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With