我们能用 C++20 构造带有视图的容器吗?

ein*_*ica 11 c++ range-v3 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;
}
Run Code Online (Sandbox Code Playgroud)

是一个打印的有效程序9 16 25

与 range-v3 库一起编译,这是值得的。

Bar*_*rry 10

我的问题:我们是否能够构建(现有)任何范围的标准库容器?更重要的是,具有范围视图?

不可以。唯一可以从满足正确标准的任意范围构建的标准库组件是std::span<T>.

标准库可能会采用的方向是 range-v3 也朝着的方向(请注意,range-v3 中的链接示例确实可以编译,但会警告已弃用的转换) - 使用帮助程序为您进行转换:

std::vector<int> squares =
    std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;
Run Code Online (Sandbox Code Playgroud)

从您正在使用的示例中可以看出不采用范围构造函数的原因之一:

std::vector<int> squares { std::ranges::views::transform(vec, sq) };
Run Code Online (Sandbox Code Playgroud)

考虑一下该声明与这两个声明有何不同:

std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );
Run Code Online (Sandbox Code Playgroud)

v必然是一个vector<transform_view<...>>包含单个transform_view,而w将是一个vector<int>

此外,向标准库添加更多、仔细约束的容器构造函数无论如何都不会帮助第三方容器类型 - 而像这样的工具ranges::to在所有情况下都能很好地工作。

  • @EricNiebler 完全正确:-)他们看起来_一样。他们不一样。 (7认同)