C++ 范围视图到std::vector
在建议的C++20(One)范围TS中,建议的将视图转换为std::vector的方法是什么 以下代码未编译:C++ 范围视图到std::vector,c++,vector,range,C++,Vector,Range,在建议的C++20(One)范围TS中,建议的将视图转换为std::vector的方法是什么 以下代码未编译: int main() { std::vector<float> values = {1.0, 2.0, 3.0, 4.0, 5.2, 6.0, 7.0, 8.0, 9.0
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);
}
int
main(){
向量值={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(值,[](float v){return v<5.f;}));
std::vector foo=vw::filter(值,[](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; });
。/src/view.cpp:19:40:错误:请求将“std::experional::ranges::v1::filter\u view”转换为非标量类型“std::vector”
std::vector foo=vw::filter(值,[](float v){return v<5.f;});
(由于某些CV限制,注释行也不会编译)
那么,除了使用基于范围的for循环之外,我如何处理视图
还有一些额外的问题:
将视图转换为
std::vector
(或者任何其他容器)的C++20方法是将范围的begin
和end
成员传递给vector
构造函数,该构造函数接受2个迭代器(以及可选的分配器)
我也在寻找这个问题的答案。我真正想要的是std::vector
的构造函数重载,接受一个范围。大约:
template <std::ranges::input_range R>
vector(R&& r) : vector(r.begin(), r.end()) {
}
模板
向量(R&&R):向量(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()};
}
名称空间rng=std::ranges;
模板
constexpr自动到_向量(R&R){
使用elem\u t=std::decation\u t;
返回std::vector{r.begin(),r.end()};
}
这很有效,但不是很“瘦小”:
然后我做得更好了一点:
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>{};
}
名称空间详细信息{
//类型充当一个标记,以查找正确的运算符|重载
模板
结构到辅助对象{
};
//这确实起作用了
模板
需要std::可转换为
容器操作员|(R&R,to|U助手){
返回容器{r.begin(),r.end()};
}
}
//找不到容器的概念,但是
//容器是一个范围,但不是视图。
模板
需要(!rng::view)
自动到(){
返回detail::to_helper{};
}
毫无疑问,对于sized_range
s和具有reserve
成员函数的容器,如std::vector
,人们可以做得更好
有人建议在C++23()中添加一个
到
函数,我相信这会做得更好。因此,除了使用基于范围的for循环之外,如何使用视图取决于您想要做什么。在不知道我们真的不能建议怎么做的情况下。使用copy
怎么样?它在C++20中有了新的定义:那么除了使用基于范围的for循环之外,我如何处理视图呢?简单地说:你还需要什么?通过在视图上迭代,您几乎可以做任何您想做的事情。但是stl确实给了你更多的选择:大多数stl算法都有一个范围变量(我认为有些是迭代器无法实现的)。此外,还有一个非常好的|
操作符可以在范围上应用视图。创建一个空容器并使用std::copy确实值得一试。我只是想知道为什么这两种情况都发生了,分配给容器和范围::to被丢弃了w.r.t.范围-v3。对于那些想知道我想做什么的人:我想将延迟求值的视图显化到一个实际的容器中——也就是说,代码片段中到底做了什么。你能链接一个在线编译器,让我们从一开始就使用它吗?