c ++ 范围适配器 std::views::common()

434 阅读2分钟

主要范围适配器

C++提供了多个范围适配器,可轻松创建具有最佳性能的视图。

其中一些适配器适用于特定的视图类型。但是,其中一些可能会根据传递范围的特征创建不同的东西。

例如,如果适配器已经具有结果的特征,则它们可能会生成传递的范围。

有几个主要的适配器可以轻松创建视图或将范围转换为具有特定特征(独立于内容)的视图。这些适配器是:

  • std::views::a11 (),它是为传递的范围生成视图的主要适配器
  • std::views::counted(),是将开始和计数转换为视图的主要适配器
  • std::views::common (),它为开始迭代器和 sentinel(结束迭代器)生成具有协调类型的视图,以便能够将范围/视图传递给传统的范围参数

c ++ 范围适配器common ()

范围适配器std::views::common()为传递的范围生成一个具有统一类型的开始迭代器和哨兵(结束迭代器)的视图。

它的作用类似于范围适配器std::views::al1(),如果它的迭代器具有不同的类型,它会从传递的参数创建一个std::ranges::common视图。

例如,假设我们要调用一个传统算法algorithm(),该算法要求开始迭代器和结束迭代器的类型相同。然后我们可以为可能不同类型的迭代器调用它,如下所示

template<typename TBeg, typename TEnd>

void callAlgo(TBeg beg, TEnd end)

{

auto v = std::views::common(std::ranges::subrange(beg,end));

algo(v.begin(), v.end()); //假设algorithm()要求具有相同类型的迭代器

}

common(rg) yields:

  • 如果 rg 已经是具有 samne 开始和结束迭代器类型的视图,则为 rg 的副本
  • 如果 std::ranges::ref_view 是具有相同开始和结束迭代器类型的范围对象,则为 rgstd::ranges::
  • 否则,std::ranges:: rgcommon view

例如

std::list<int> 1st;

std::ranges::iota_view iv{1,10};

...

auto v1 =std::views::common(1st); //std::ranges::ref_view<decltype(1st)>

  
auto v2 =std::views::common(iv);//decltype(iv)

auto v3 = std::views::common(std::views::all(vec));

//std::ranges::ref_view<decltype(1st)>

  

std::list<int> 1st {1,2,3,4,5,6,7,8,9};

auto vt = std::views::take(1st,5);  //begin() and end() have different types

auto v4 = std::views::common(vt);  //std::ranges::common_view<decltype(vt)>

std::ranges::common视图的构造函数和辅助类型std::common:iterator都要求传递的迭代器具有不同的类型。所以,如果你不知道迭代器类型是否不同,你应该使用这个适配器。


开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 N 天,点击查看活动详情