Generic Types of Ranges
类型萃取从字面意思上来说其实就是帮助我们挑选某个对象的类型,筛选特定的对象来做特定的事。可以先来回顾一下以前的写法。
#include
#include
int main() {
std::vector v{1, 2, 3};
using iterator_type = std::vector::iterator;
using difference_type = std::iterator_traits::difference_type;
using iterator_catogory = std::iterator_traits::iterator_category;
using pointer = std::iterator_traits::pointer;
using reference = std::iterator_traits::reference;
using value_type = std::iterator_traits::value_type;
}
到了C++20,我们有了ranges,我们有了更多强大的工具,可以说它们是处理ranges的强大工具,我们来看看具体的内容。
通过上图,很多内容都直观明了服务器托管网,为了避免晦涩难懂的抽象话术,我们通过代码来看看具体用法。
#include
#include
#include
#include
#include
int main() {
std::vector v{10, 20, 30};
static_assert(std::is_same_v::difference_type,
std::iterator_traits::difference_type>); // OK
static_assert(std::is_same_v::pointer,
std::iterator_traits::pointer>); // OK
static_assert(std::is_same_v::reference,
std::iterator_traits::reference>); // OK
static_assert(std::is_same_v::value_type,
std::iterator_traits::value_type>); // OK
static_assert(std::is_same_v::iterator_cat服务器托管网egory,
std::iterator_traits::iterator_category>); // OK
// 可以明显看到,比起传统的迭代器萃取,C++20的处理方式更加简洁,只用传入ranges类型,而不用传入迭代器类型,或许这就是ranges的魅力所在。
static_assert(std::is_same_v,
decltype(end(v))>); // OK
// 获取哨兵类型。
static_assert(std::is_same_v,
decltype(v[0])>); // OK, both are int&
static_assert(std::is_same_v,
std::remove_reference_t>); // Error, int& and int
static_assert(std::is_same_v,
std::remove_reference_t>); // OK, both are int
static_assert(std::is_same_v,
decltype(v[0])>); // Error, int and int&
static_assert(std::is_same_v,
std::size_t>); // OK
static_assert(std::is_same_v,
std::ptrdiff_t>); // OK
static_assert(std::is_same_v,
decltype(std::move(v[0]))>); // OK
static_assert(std::is_same_v,
std::ranges::dangling>); // OK
static_assert(std::is_same_v,
std::ranges::dangling>); // OK
}
Generic Types of Iterators
回到迭代器这一话题,为了更好的支持新的迭代器类型特征,你应该用如下的方式来代替传统的类型萃取。
#include
#include
#include
#include
int main() {
std::vector v{1, 2, 3};
using iterator_type = std::vector::iterator;
static_assert(std::is_same_v>, int>);
static_assert(std::is_same_v>, int&>);
static_assert(std::is_same_v>, int&&>);
static_assert(std::is_same_v>, std::ptrdiff_t>);
using type1 = std::common_reference_t; // int
using type2 = std::common_reference_t; // int
using type3 = std::common_reference_t; // int&
using type4 = std::common_reference_t; // const int&
using type5 = std::common_reference_t; // int&&
}
common_reference_t过于复杂,暂且先跳过。可以看到,这也是萃取类型的一种方式,只不过写法不同罢了。话说回来,std::ranges::range_value_t其实就是std::iter_value_t>的简化。
New Functional Types
std::identity是一个函数对象,返回对象本身,可以搭配ranges的算法一起使用。
#include
#include
#include
#include
#include
int main() {
std::vector v{1, 2, 3};
auto pos = std::ranges::find(v, 9, [](auto x) { return x * x; });
if (pos != end(v))
std::cout
pos处传入一个lambda表达式,对容器当中的每一个元素进行平方,然后返回对应的迭代器。pos2处传入的正是std::identity,即对象自身,相当于不对原容器进行任何的具体操作,它跟pos3本质上是相同的。
std::compare_three_way也是一个函数对象,它与这个运算符有关联。这个运算符有个有意思的名字,叫宇宙飞船运算符,因为它的形状长得像宇宙飞船。这是C++20比较有意思的一个特性。
#include
#include
#include
int main() {
int a{3}, b{4};
auto result = (a b);
if (result bn";
}
Other New Types for Dealing with Iterators
C++20,还有更多的值得探索……
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
关键字 oracle lock 问题描述 Oracle 数据库上锁问题如何排查 解决问题思路 准备数据 create table lock_test(name varchar(10),age varchar(10)); insert into lock_tes…