我们能否在 C++20 中构建带有视图的容器?
Will we be able to construct containers with views in C++20?
范围将随 C++20 标准版本一起用于 C++。
我的问题:我们能否构建(现有的)任何范围的标准库容器?更重要的是,具有范围视图?
例如,会这样:
#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;
}
是一个打印 9 16 25
的有效程序吗?
My question: Will we be able to construct (existing) standard-library containers with any range? And more importantly, with range views?
没有。唯一可从满足正确条件的任意范围构建的标准库组件是 std::span<T>
.
标准库可能采用的方向是 range-v3 也将采用的方向(请注意,range-v3 中的链接示例确实可以编译,但会警告已弃用的转换)- 使用 a helper 为您进行转换:
std::vector<int> squares =
std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;
从您使用的示例中可以看出不采用范围构造函数的原因之一:
std::vector<int> squares { std::ranges::views::transform(vec, sq) };
考虑一下该声明与这两个声明有何不同:
std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );
v
必然是包含单个 transform_view
的 vector<transform_view<...>>
,而 w
将是 vector<int>
。
此外,向标准库添加更多、仔细约束的容器构造函数无论如何都不会帮助第三方容器类型——而像 ranges::to
这样的工具在所有情况下都能完美运行。
范围将随 C++20 标准版本一起用于 C++。
我的问题:我们能否构建(现有的)任何范围的标准库容器?更重要的是,具有范围视图?
例如,会这样:
#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;
}
是一个打印 9 16 25
的有效程序吗?
My question: Will we be able to construct (existing) standard-library containers with any range? And more importantly, with range views?
没有。唯一可从满足正确条件的任意范围构建的标准库组件是 std::span<T>
.
标准库可能采用的方向是 range-v3 也将采用的方向(请注意,range-v3 中的链接示例确实可以编译,但会警告已弃用的转换)- 使用 a helper 为您进行转换:
std::vector<int> squares =
std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;
从您使用的示例中可以看出不采用范围构造函数的原因之一:
std::vector<int> squares { std::ranges::views::transform(vec, sq) };
考虑一下该声明与这两个声明有何不同:
std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );
v
必然是包含单个 transform_view
的 vector<transform_view<...>>
,而 w
将是 vector<int>
。
此外,向标准库添加更多、仔细约束的容器构造函数无论如何都不会帮助第三方容器类型——而像 ranges::to
这样的工具在所有情况下都能完美运行。