将视图范围设置为std::vector

Range view to std::vector

本文关键字:std vector 设置 视图 范围      更新时间:2023-10-16

在所提出的C++20(the One(Ranges TS中,将视图转换为std::矢量的方法是什么?

以下代码未编译:

int                                           
main() {                                                        
std::vector<float> values = {1.0, 2.0, 3.0, 4.0, 5.2, 6.0, 7.0, 8.0, 9.0}; 
//fmt::print("{}n", std::experimental::ranges::views::filter(values, [] (float v) { return v < 5.f; })); 
std::vector<float> foo = vw::filter(values, [] (float v) { return v < 5.f; }); 
fmt::print("{}n", foo);                
}

错误

../src/view.cpp:19:40: error: conversion from     ‘std::experimental::ranges::v1::filter_view<std::experimental::ranges::v1::ref_view<std::vector<float> >, main()::<lambda(float)> >’ to non-scalar type ‘std::vector<float>’ requested
std::vector<float> foo = vw::filter(values, [] (float v) { return v < 5.f; }); 

(由于某些CV限制,注释行也不会编译(。

那么,除了使用基于范围的for循环之外,我该如何处理视图呢?

还有一些额外的问题:

  1. 我使用的cmcst2实现是否遵循了建议?范围v3似乎不是
  2. 是否有关于量程TS的文件?我发现的提案PDF几乎是一个格式糟糕的diff风格的代码转储。事实上,直接阅读cmcst2的来源对我来说更容易阅读。cppreference似乎也缺乏
将视图转换为std::vector(或任何其他容器(的C++20方法是将范围的beginend成员传递给接受2个迭代器(和一个可选分配器(的vector构造函数。

我也在寻找这个问题的答案。我真正想要的是std::vector的构造函数重载,接受一个范围。大约:

template <std::ranges::input_range R>
vector(R&& r) : vector(r.begin(), r.end()) {
}

但在C++20中没有。

首先,我实现了这个:

namespace rng = std::ranges;
template <rng::range R>
constexpr auto to_vector(R&& r) {
using elem_t = std::decay_t<rng::range_value_t<R>>;
return std::vector<elem_t>{r.begin(), r.end()};
}

这是有效的,但不是很";rangy":https://godbolt.org/z/f2xAcd

然后我做得更好:

namespace detail {
// Type acts as a tag to find the correct operator| overload
template <typename C>
struct to_helper {
};

// This actually does the work
template <typename Container, rng::range R>
requires std::convertible_to<rng::range_value_t<R>, typename Container::value_type>
Container operator|(R&& r, to_helper<Container>) {
return Container{r.begin(), r.end()};
}
}
// Couldn't find an concept for container, however a
// container is a range, but not a view.
template <rng::range Container>
requires (!rng::view<Container>)
auto to() {
return detail::to_helper<Container>{};
}

https://godbolt.org/z/G8cEGqeq6

毫无疑问,对于sized_range和像std::vector这样具有reserve成员函数的容器可以做得更好。

有人建议在C++23中添加一个to函数(https://wg21.link/p1206)我相信这会做得更好。