本质:
    语法糖,编译器还是会转化为for循环的调用形式

    转换形式的衍化:
    C++11 / C++17 / C++20

    1. // C++17之前
    2. {
    3. auto && __range = 范围表达式 ;
    4. for (auto __begin = 首表达式, __end = 尾表达式 ; __begin != __end; ++__begin) {
    5. 范围变量声明 = *__begin;
    6. 循环语句
    7. }
    8. }
    1. // C++17起 C++20之前
    2. {
    3. auto && __range = 范围表达式 ;
    4. auto __begin = 首表达式 ;
    5. auto __end = 尾表达式 ;
    6. for ( ; __begin != __end; ++__begin) {
    7. 范围变量声明 = *__begin;
    8. 循环语句
    9. }
    10. }
    1. // C++20起
    2. {
    3. 初始化语句
    4. auto && __range = 范围表达式 ;
    5. auto __begin = 首表达式 ;
    6. auto __end = 尾表达式 ;
    7. for ( ; __begin != __end; ++__begin) {
    8. 范围变量声明 = *__begin;
    9. 循环语句
    10. }
    11. }

    从这一系列的衍化,可以看出来是一个不断修复bug的过程,不断完善的过程
    C++ 17 —> C++ 20 增加了初始化语句:

    1. #include <iostream>
    2. #include <vector>
    3. int main()
    4. {
    5. for (auto n = v.size(); auto i : v) // 初始化语句(C++20)
    6. std::cout << --n + i << ' ';
    7. std::cout << '\n';
    8. }

    使用常量左值引用读元素 :

    1. #include <iostream>
    2. #include <vector>
    3. int main()
    4. {
    5. std::vector <int> arr = {1,2,3,4,5};
    6. for(const int& i : arr){
    7. std::cout << i << std::endl;
    8. }
    9. }

    使用 万能引用( universal reference )修改元素 :

    1. #include <iostream>
    2. #include <vector>
    3. int main()
    4. {
    5. std::vector <int> arr = {1,2,3,4,5};
    6. for(auto&& i : arr){
    7. i = i + 1;
    8. }
    9. }