#include <initializer_list> 需要在基于范围的 for 中使用初始值设定项列表?

#include <initializer_list> required to use initializer list in range-based for?

本文关键字:for 列表 list gt initializer lt #include 于范围 范围      更新时间:2023-10-16

最终的C++11标准包括基于范围的for的规定,以便"仅适用于"本机数组,而不必包括<iterator>或任何其他标头。据我所知,这是英国第78和79号评论意见的结果,在第2900号工作文件中首先谈到的。

该提案还包括在每个翻译单元中隐含#include <initializer_list>的规定,以便例如程序

#include <iostream>
int main()
{
    for (auto i : { 1, 2, 3, 4, 5 })
        std::cout << i << "n";
}

即使不包括CCD_ 3也将是符合标准的。

然而,当概念从C++11中删除时,基于范围的进行了修订,如n2930所示。虽然数组"只工作"的规定仍然存在,但没有提到初始化器列表也是如此;事实上,各种标准库容器标题将#include <initializer_list>的规范和8.5.4.2的最终文本暗示了与我相反的情况。

据我所知,这与该主题的最终措辞非常接近。那么,关于最终标准,上面的程序是否形成良好,或者我是否需要#include <initializer_list>,甚至在基于的范围内使用它?换句话说,根据FDIS的8.5.4.2,在基于的范围中使用初始值设定项列表是否构成"std::initializer_list的使用——甚至是未命名类型的隐式使用"?

我会答应的。根据§6.5.4【标准范围】/1,陈述

for (auto i : { 1, 2, 3, 4, 5 })
    ...

相当于

auto&& __range = { 1, 2, 3, 4, 5 };
...

这意味着使用initializer_list<int>并且需要包括<initializer_list>报头。

GCC 7.1在不包括<initializer_list>的情况下会产生以下错误:

error: deducing from brace-enclosed initializer list requires #include <initializer_list>
     for (auto i : { 1, 2, 3, 4, 5 })
                                   ^

要看到这个错误,应该省略<iostream>,因为包括<iostream>也将包括<initializer_list>