C++ 范围视图到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

在建议的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}; 
    //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循环之外,我如何处理视图

还有一些额外的问题:

  • 我使用的cmcstl2实现是否符合建议?ranges-v3似乎不是
  • 是否有关于TS范围的文件?我发现的PDF提案几乎是一个格式非常差的代码转储。事实上,直接阅读cmcstl2源代码对我来说更容易阅读。参考文献似乎也缺乏

  • 将视图转换为
    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。对于那些想知道我想做什么的人:我想将延迟求值的视图显化到一个实际的容器中——也就是说,代码片段中到底做了什么。你能链接一个在线编译器,让我们从一开始就使用它吗?