提问者:小点点

C++20视图范围到矢量


现在C++20ranges实现实际上已经在这里并且在GCC10.2下发布了,我想知道如何将ranges视图转换回一个实际的容器,比如一个向量。 我发现了这个问题(从视图到std::vector),它对预发布版本提出了同样的要求,但是我想知道,自从它发布以来,是否有任何新的方法将视图转换为容器? 还是那个问题的单一答案仍然是最好的解决方案?


共1个答案

匿名用户

最简单的方法就是使用range-v3,它有一个转换运算符。 从示例中可以看出:

using namespace ranges;
auto vi =
    views::for_each(views::ints(1, 10), [](int i) {
        return yield_from(views::repeat_n(i, i));
    })
  | to<std::vector>();
// vi == {1,2,2,3,3,3,4,4,4,4,5,5,5,5,5,...}

否则,链接问题中的答案并不完全准确,因为一个范围可能不具有相同的迭代器和哨兵类型,而答案需要相同的迭代器和哨兵类型。 所以我们可以做得更好一点:

template <std::ranges::range R>
auto to_vector(R&& r) {
    std::vector<std::ranges::range_value_t<R>> v;

    // if we can get a size, reserve that much
    if constexpr (requires { std::ranges::size(r); }) {
        v.reserve(std::ranges::size(r));
    }

    // push all the elements
    for (auto&& e : r) {
        v.push_back(static_cast<decltype(e)&&>(e));
    }

    return v;
}

上面的一个较短版本不一定预先保留所有相同的位置,它通过使用views::common:

template <std::ranges::range R>
auto to_vector(R&& r) {
    auto r_common = r | std::views::common;
    return std::vector(r_common.begin(), r_common.end());
}

这里缺少保留的典型例子是使用std::list调用to_vector(),它有一个O(1)size()可用,可用于保留,但一旦进入迭代器,就会丢失这个值。

相关问题


MySQL Query : SELECT * FROM v9_ask_question WHERE 1=1 AND question regexp '(c++20|视图|矢量)' ORDER BY qid DESC LIMIT 20
MySQL Error : Got error 'repetition-operator operand invalid' from regexp
MySQL Errno : 1139
Message : Got error 'repetition-operator operand invalid' from regexp
Need Help?