您的位置 首页 > 德语词汇

ranges是什么意思?用法、例句?c++20 的ranges是什么?

各位老铁们,大家好,今天由我来为大家分享ranges是什么意思?用法、例句,以及c++20 的ranges是什么?的相关问题知识,希望对大家有所帮助。如果可以帮助到大家,还望关注收藏下本站,您的支持是我们最大的动力,谢谢大家了哈,下面我们开始吧!

c++20四大特性为coroutine,module,concept和range。本文将对range进行探索。

ranges是什么意思?用法、例句?c++20 的ranges是什么?

首先看看range的定义,range其实是一个concept,concept用于对模板的参数进行一定的约束,而range的约束就是要求ranges::begin(t)和ranges::end(t)可以被正常的解析。

template<classT>\nconceptrange=requires(T&t){\nranges::begin(t);//equality-preservingforforwarditerators\nranges::end(t);\n};

ranges::begin(t)和ranges::end(t)可以正常被解析的话,T需要具备哪些条件呢?

这里阅读了下面网站的解析,https://eel.is/c++draft/range.access.begin,openinnewwindow得到的结论是,T可能在下面几种条件下是合法的:

这里又引出了一个概念input_or_output_iterator,其定义如下,阅读了一下,大概意思就是其可以被解引用*,并且支持++操作。(解释并不严谨,但是便于理解)

template<classI>\nconceptinput_or_output_iterator=\nrequires(Ii){\n{*i}->/*can-reference*/;\n}&&\nstd::weakly_incrementable<I>;

到此为止,我们基本了解了什么样的内容可以称之为一个range,把上面的语句重新解释一下,

对于模板类型T,当T满足下面的条件时,是一个range:

本文并不是一个学术论文,上面的总结可能不能很严谨地囊括所有方面,但是足以让你对range的概念有了相对全面的认识。

例如STL中的vector,对于表达式vector<int>v,v.begin()和v.end()是合法的,并且v.begin()和v.end()返回的值支持使用解引用和++操作符。

ranges可以帮我们简化代码的书写:

#include<iostream>\n#include<vector>\n#include<ranges>\n#include<algorithm>\n\nintmain()\n{\nstd::vector<int>vec{2,7,4,10,5,1};\nstd::ranges::sort(vec);//std::sort(vec.begin(),vec.end());\nfor(autoit=vec.cbegin();it!=vec.cend();++it){\nstd::cout<<*it<<std::endl;\n}\n}结合ranges::view简化反向,过滤,取值等操作

下面的例子使用了ranges::view::reverse帮助我们对vector进行反向。

#include<iostream>\n#include<vector>\n#include<ranges>\n#include<algorithm>\n\nusingnamespacestd::ranges;\n\nintmain()\n{\nstd::vector<int>a{1,2,3,4,5};\nfor(inti:(a|views::reverse))\n{\nstd::cout<<i;\n}\n}

这里出现了管道类似于shell指令中的管道运算符|,其作用也是类似的,将前一个表达式的输出作为下一个表达式的输入。

例如下面的例子,对range首先进行adapter1操作,再进行adapter2操作。语法1和语法2是等同的,但是语法2更好理解。

adapter2(adaptor1(range,args...),args...)//(1)\n\nrange|adaptor1(args...)|adaptor2(args...)//(2)

所以上述代码中的a|views::reverse的含义就更好理解了,就是将a作为views::reverse的输入,将就可以得到一个a反向版本的range。再对这个反向版本的range进行遍历。

看懂了上面的简单的例子,我们再看下面的复杂一点的例子:

#include<iostream>\n#include<vector>\n#include<ranges>\n#include<algorithm>\n\nusingnamespacestd::ranges;\n\nintmain(){\nstd::vector<int>v{1,2,3,4,5,6,7,8};\nautores=v|views::filter([](inta){returna%2;})|views::take(3);\nfor(constauto&i:res){\nstd::cout<<i<<std::endl;\n}\n}

在这个例子中,首先将v传递给filter函数,filter函数的作用是过滤出v中奇数的元素,再将这个中间结果传递给下一层的take方法,取出前三个元素。

从上面的例子中我们大概对range有了认识,range实际上是一种泛化,是对具有相同接口的数据结构的一种抽象。有人也形象的称之为STL2.0。

下面我们就看看如何自定义一个range类型。

在下面的例子中,我们定义了MyRange的类型,提供了相应的begin和end方法。由于我们私有数据类型是vector,因此begin和end返回的是迭代器类型,也是满足要求的。

//g++main.cpp-std=c++20\n#include<array>\n#include<iostream>\n#include<list>\n#include<ranges>\n#include<vector>\n\n\nusingnamespacestd::ranges;\n\ntemplate<typenameT>\nclassMyRange\n{\npublic:\nMyRange(){\n\n}\n~MyRange()\n{\n\n}\npublic:\ntypedefstd::vector<T>::iteratorIterator;\nIteratorbegin()\n{\nreturnv_.begin();\n}\n\nIteratorend()\n{\nreturnv_.end();\n}\n\nvoidpush_back(Tt){\nv_.push_back(t);\n}\nprivate:\nstd::vector<T>v_;\n};\n\nintmain()\n{\nMyRange<int>myRange;\nmyRange.push_back(5);\nmyRange.push_back(2);\nmyRange.push_back(3);\nmyRange.push_back(7);\nmyRange.push_back(9);\n\nfor(inti:(myRange|views::reverse))\n{\nstd::cout<<i;\n}\n}总结

通过上面的例子,我们对range有了一个认识,ranges库提供的功能不仅仅局限于此,有关ranges的更多作用,可以去下面的地址进行了解。https://en.cppreference.com/w/cpp/ranges。

好了,关于ranges是什么意思?用法、例句和c++20 的ranges是什么?的问题到这里结束啦,希望可以解决您的问题哈!

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023