range-for

以前容易出现引用悬挂的问题。在新的语言标准中得到了改进。

C++11 只是简单的语法糖,只能保证表达式返回值被临时变量接受并保留到循环结束:(https://stackoverflow.com/a/51440883)

{
    auto&& __range = f()[5]; // (*)
    auto __begin = __range.begin(); // not exactly, but close enough
    auto __end = __range.end();     // in C++17, these types can be different
    for (; __begin != __end; ++__begin) {
        auto e = *__begin;
        // rest of body
    }
}

C++20 range-for 生命周期规则一样,不过可以在里面创建临时对象,避免后面引用过程中的悬挂:

#include <iostream>

int main() {
    for (auto lst = {1, 2, 5, 1, 71}; auto i : lst) {
        std::cout << i << '\n';
    }
}

C++23 则要求在 range-for 括号中创建的临时对象生命周期延长到整个循环结束后。不过截至 2023 年 6 月 3 日,没有编译器实现。