C ++ 20引入了std::common_reference
。目的是什么?有人可以举一个使用它的例子吗?
std::common_reference
是我为容纳代理迭代器而对STL迭代器进行概念化的努力。
在STL中,迭代器具有两种相关的特殊类型:common_reference
和reference
。前者是迭代器的value_type
的返回类型,而operator*
是序列元素的(非常量,非引用)类型。
通用算法通常需要执行以下操作:
value_type
...因此,我们知道这两种类型之间必须存在some关系。对于非代理迭代器,关系很简单:value_type tmp = *it;
始终为reference
,可以选择使用const和引用限定。 value_type
要求表达式Early attempts at defining the InputIterator
concept可转换为InputIterator
,并且对于大多数有趣的迭代器而言就足够了。]
我希望C ++ 20中的迭代器比这更强大。例如,考虑需要以锁步方式迭代两个序列的*it
。取消引用const value_type &
时,会得到两个迭代器的zip_iterator
zip_iterator
。因此,pair
的reference
和zip
将具有以下关联类型:[vector<int>
迭代器的vector<double>
:zip
reference
迭代器的pair<int &, double &>
:zip
如您所见,仅通过添加顶级cv-和ref限定符,这两种类型就不会相互关联。但是,让两种类型任意不同会让人感到错误。显然,这里有some
关系。但是两者之间的关系是什么,在迭代器上运行的通用算法可以安全地假设这两种类型呢?C ++ 20中的答案是,对于any
有效的迭代器类型(是否为代理),类型value_type
和pair<int, double>
共享common reference。换句话说,对于某些迭代器reference &&
,有一些类型value_type &
使以下格式正确:it
CR
是通用参考。所有算法都可以依靠这种类型存在的事实,并可以使用void foo(CR) // CR is the common reference for iterator I {} void algo( I it, iter_value_t<I> val ) { foo(val); // OK, lvalue to value_type convertible to CR foo(*it); // OK, reference convertible to CR }
进行计算。
因此,这就是CR
在C ++ 20中的STL中扮演的角色。通常,除非您正在编写通用算法或代理迭代器,否则可以放心地忽略它。它可以确保您的迭代器履行其合同义务。