c++ - 使用基于范围的 for 迭代临时 std::initializer_list

标签 c++ visual-studio c++11 undefined-behavior compiler-bug

鉴于此代码

#include <iostream>
#include <initializer_list>
#include <string>

int a, b;

int main() {
    for (auto p : std::initializer_list<std::pair<int &, std::string>>{
        { a, "a" },
        { b, "b" },
    })
    {
        std::cout << p.second << ": " << p.first << '\n';
    }
}

我期望输出

a: 0
b: 0

gccclang不过,同意Visual Studio 2013 Update 5(我的版本,不确定 rextester 使用什么)不同意并打印此内容:

: 0
: 0

Visual Studio 有一个 issuestd::initializer_list 一起使用,但应该自更新 2 以来已修复。

这是 Visual Studio 中的错误还是我调用了未定义或未指定的行为?

最佳答案

摘自 cppreference 的“说明”部分,范围 for 循环相当于:

{
    auto && __range = range_expression ;
    for (auto __begin = begin_expr,
                __end = end_expr;
            __begin != __end;
            ++__begin) {
        range_declaration = *__begin;
        loop_statement
    }
}

您可以看到迭代范围 (range_epxression) 绑定(bind)到转发引用。在您的情况下,后者会变成右值引用,因为您的 initializer_list 是临时的,因此它的生命周期会扩展到整个 for 循环。

MSVC 这里是错误的。

关于c++ - 使用基于范围的 for 迭代临时 std::initializer_list,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33303325/

相关文章:

c++ - 在 C++ 中使用 auto 声明变量有缺点吗?

c++ - 使用 std::find 查找从二进制文件读取的字符并转换为 std::vector<string> 中的 std::string 会产生这种不可预测的行为吗?

c++ - 将带有捕获的 lambda 传递给遗留回调

c# - 断点和异常停止正常工作,xamarin android

visual-studio - 无法运行应用程序的调试版本

c++ - 如何参数化构造函数的参数个数?

c++ - 防止对不同大小的、模板化的、多态的、数学 vector 进行组件操作

c++ - 如何创建不同类型的多维 vector/数组?

c++ - 运行后台进程 linux 简单 shell。 C++

c# - 强类型数据集 (.xsd) 错误 VS Community Edition 15.8.1