范围TS成语和神秘的汽车&&

时间:2018-07-22 01:16:10

标签: c++ c++20

在前TS代码中,我可能会执行以下操作来获取对ForwardIterator值的(可能是可修改的)引用:

auto &val = *it;

这也将在此类迭代器的基于范围的for循环中使用:

for(auto &val : some_range)

但是,在基于C ++ 20和Range TS的代码中,我看到在这些位置有许多auto&&用法。我从语言的角度理解auto&&在做什么。我不明白的是为什么auto&应该可以正常工作时在这些地方使用它?这种性质的大多数代码都不会转发引用,那么为什么要使用转发引用来捕获它呢?

1 个答案:

答案 0 :(得分:11)

使用此习惯用法是因为Range TS和C ++ 20等效的实际上需要该习惯用法。之所以要这样做,是因为代理迭代器现在是所有迭代器类别的合法构造。

代理迭代器的operator*不返回value_type&;它会返回一个像引用一样起作用的对象的prvalue。因此,如果您尝试使用auto&存储对该值的引用,则代码将无法使用代理迭代器进行编译。

Range TS的迭代器概念从不要求operator*的返回值实际上是语言参考。可读概念仅要求返回值可转换为value_type。可写概念仅要求将value_type分配给返回值。

因此,在范围功能下从各种迭代器获取引用的代码现在必须使用auto&&,它可以绑定到prvalue,而无需使其成为const。因此,在处理范围时,如果要获取对该值的可能是非常量的引用,则auto&&是最方便的方法。如果只需要const引用,则可以继续使用const auto &


请注意,auto&&还处理直接从其value_type返回operator*类型的prvalue的迭代器。显然,这些仅对Readable迭代器有用,但是它们非常有用。最简单的示例是一个迭代器,用于对一定数量的整数进行计数。迭代器返回int,而不是对某些内存的引用。由于对返回语言参考没有严格要求,因此此类迭代器可以是Range TS中的RandomAccessIterators。

这样的迭代器对于正则表达式匹配也很有意义。当前的regex_iterator返回对内部对象的引用;对于Forw​​ardIterator来说这是必需的。取而代之的是,通过operator*进行搜索并将匹配对象作为prvalue返回,它可以变得更小。但是旧系统不允许这样做。

鉴于这种迭代器,auto&不能用于捕获对其结果的“引用”。