康桓瑋*_*康桓瑋 26 c++ metaprogramming type-traits c++20
C ++ 20引入std::common_reference
。目的是什么?有人可以举一个使用它的例子吗?
Eri*_*ler 24
common_reference
从我的努力出发,提出了可容纳代理迭代器的STL迭代器的概念化。
在STL中,迭代器具有两种相关的特殊类型:reference
和value_type
。前者是迭代器的返回类型operator*
,而value_type
is是序列元素的(非常量,非引用)类型。
通用算法通常需要执行以下操作:
value_type tmp = *it;
Run Code Online (Sandbox Code Playgroud)
...所以我们知道这两种类型之间一定存在某种关系。对于非代理迭代器,关系很简单:reference
始终为value_type
,可选为const和引用限定。早期定义该InputIterator
概念的尝试要求该表达式*it
可转换为const value_type &
,并且对于大多数有趣的迭代器而言已足够。
我希望C ++ 20中的迭代器比这更强大。例如,考虑zip_iterator
在锁步中迭代两个序列的a的需求。取消引用a时zip_iterator
,将获得pair
两个迭代器reference
类型的临时类型。因此,zip
'ing a vector<int>
和a vector<double>
将具有以下关联类型:
zip
迭代器的reference
:pair<int &, double &>
zip
迭代器的value_type
:pair<int, double>
如您所见,仅通过添加顶级cv-和ref限定条件,这两种类型就不会相互关联。但是,让两种类型任意不同会让人感到错误。显然这里有一些关系。但是两者之间的关系是什么,在迭代器上运行的通用算法可以安全地假设这两种类型呢?
在C ++ 20中的答案是,对于任何有效的迭代器类型,代理与否,其种类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
}
Run Code Online (Sandbox Code Playgroud)
CR
是通用参考。所有算法都可以依赖这种类型存在的事实,并可以std::common_reference
用来计算它。
因此,这就是common_reference
C ++ 20中STL中扮演的角色。通常,除非您正在编写通用算法或代理迭代器,否则可以放心地忽略它。它可以确保您的迭代器履行其合同义务。