栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++基础第5章:语句(2)——基于范围的for循环、语句的综合应用(达夫设备)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++基础第5章:语句(2)——基于范围的for循环、语句的综合应用(达夫设备)

文章目录
  • 1.基于范围的for循环(重要)
    • 1.1.基于范围for循环背后原理
    • 1.2.使用常量左值引用读元素
    • 1.3.使用万能引用(universal reference)修改元素
  • 2.语句的综合应用——达夫设备
    • 2.1.循环展开实例代码

1.基于范围的for循环(重要)

1.1.基于范围for循环背后原理


注意解释中,auto &&是一个万能引用(universal reference),一般来说写&&都是右值引用,但是这里如果前面有auto的话则是万能引用。万能引用在推导的时候会推导出具体的引用类型,有可能是左值引用,也有可能是右值引用。

  • C++17之前的推导(例如这里使用C++11):

  • C++17的推导:

  • C++20的推导:感觉不会用到,实际上明白C++17之前的原理就足够使用了。

1.2.使用常量左值引用读元素

1.3.使用万能引用(universal reference)修改元素
  • 按照简单的想法,使用auto&即可,如下所示:
  • 但是在某些情况下,auto&编译直接会报错,如下的程序中,std::vector的迭代器解引用之后并不是bool类型,而是一个中间类型,这和他其中的实现有关。此时如果使用auto&编译就会报错,而是用万能引用auto&&则没问题。因此对于修改元素的操作,推荐使用万能引用auto&&。

    上面的程序使用万能引用完整的翻译如下:
#include 
#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;
}
2.语句的综合应用——达夫设备

2.1.循环展开实例代码

假设有一个10000维的数组,我们要找其中的最大值,写一个for循环如下。注意for循环内部的数据是一个三目运算符,它的操作是非常快的,而for循环每次要判断循环是否成立、对循环变量自增,这样的操作反而更加浪费性能。

因此使用循环展开,让循环本身的操作降低比重,让更多的计算发生在循环体内部:

但是注意这样循环展开的结果有可能存在边界问题,因为如果是10000个元素,使用8个的步长是可以遍历完的。但是如果不是8的倍数个元素,那么最后的元素会访问越界。

解决方式:

  1. 方式1:比较简单但是不是特别好的方法
  2. 更优的解决方法:

  1. 再次改进:把不能整除的部分先处理,然后剩下能整除的大部分在后面处理:
  2. 终极改进:达夫设备
    注意上面的写法还是存在fallthrough 的警告,修改如下之后就没有警告了:
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1011469.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号