- 1.基于范围的for循环(重要)
- 1.1.基于范围for循环背后原理
- 1.2.使用常量左值引用读元素
- 1.3.使用万能引用(universal reference)修改元素
- 2.语句的综合应用——达夫设备
- 2.1.循环展开实例代码
注意解释中,auto &&是一个万能引用(universal reference),一般来说写&&都是右值引用,但是这里如果前面有auto的话则是万能引用。万能引用在推导的时候会推导出具体的引用类型,有可能是左值引用,也有可能是右值引用。
-
C++17之前的推导(例如这里使用C++11):
-
C++17的推导:
-
C++20的推导:感觉不会用到,实际上明白C++17之前的原理就足够使用了。
- 按照简单的想法,使用auto&即可,如下所示:
- 但是在某些情况下,auto&编译直接会报错,如下的程序中,std::vector
的迭代器解引用之后并不是bool类型,而是一个中间类型,这和他其中的实现有关。此时如果使用auto&编译就会报错,而是用万能引用auto&&则没问题。因此对于修改元素的操作,推荐使用万能引用auto&&。
上面的程序使用万能引用完整的翻译如下:
#include2.语句的综合应用——达夫设备 2.1.循环展开实例代码#include int main() { std::vector arr = std::vector >{std::initializer_list {true, false}, std::allocator ()}; { std::vector > & __range1 = arr; for(std::_Bit_iterator __begin1 = std::_Bit_iterator(__range1.begin()), __end1 = std::_Bit_iterator(__range1.end()); operator!=(__begin1, __end1); __begin1.operator++()) { std::_Bit_reference && x = __begin1.operator*(); x.operator=(false); } } return 0; }
假设有一个10000维的数组,我们要找其中的最大值,写一个for循环如下。注意for循环内部的数据是一个三目运算符,它的操作是非常快的,而for循环每次要判断循环是否成立、对循环变量自增,这样的操作反而更加浪费性能。
因此使用循环展开,让循环本身的操作降低比重,让更多的计算发生在循环体内部:
但是注意这样循环展开的结果有可能存在边界问题,因为如果是10000个元素,使用8个的步长是可以遍历完的。但是如果不是8的倍数个元素,那么最后的元素会访问越界。
解决方式:
- 方式1:比较简单但是不是特别好的方法
- 更优的解决方法:
- 再次改进:把不能整除的部分先处理,然后剩下能整除的大部分在后面处理:
- 终极改进:达夫设备
注意上面的写法还是存在fallthrough 的警告,修改如下之后就没有警告了:



