2

让我们考虑这段代码:

#include <vector>
#include <array>

int main()
{
    std::vector<std::array<int, 3>> arr;
    
    arr.push_back({ 1,2,3});          // WARNING
    arr.push_back({{4,5,6}});         // All good
    
    std::array<int, 3> a1 {1,1,1};    // WARNING
    std::array<int, 3> a2 {{2,2,2}};  // All good
    std::vector<int>   a3 {3,3,3};    // All good
    std::vector<int>   a4 {{4,4,4}};  // All good

    return 0;
}

一切都正确编译,所有向量和数组都包含预期的元素。

但是,当在 gcc 中使用标志-Wmissing-braces(用 10.2 测试)时,我们得到:

<source>:8:27: warning: missing braces around initializer for 'std::__array_traits<int, 3>::_Type' {aka 'int [3]'} [-Wmissing-braces]
    8 |     arr.push_back({ 1,2,3});          // WARNING
   11 |     std::array<int, 3> a1 {1,1,1};    // WARNING

为什么 gcc 显示此警告?这是按照https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80454中建议的错误如何修复警告:初始化器周围缺少大括号?,或者上面的两条标记线真的有问题吗?

4

1 回答 1

1

这些错误报告是关于对特殊情况发出无益的警告{0},这对于初始化C 中的任何 struct类型都是有效的,因此有时必须使用这种类型,因为未指定这种类型。

给出的代码是正确的;警告只是std::array<T,N>必须包含type 成员的通常结果T[N],因此如果您想显式初始化每个级别(有时如果正在使用其他大括号初始化),则需要额外的大括号。如果您要求您的编译器对此类事情持迂腐-Wmissing-braces态度,它会按照您的要求执行并警告速记。(std::vector<int>不需要额外的大括号,因为它使用的是初始化列表构造函数,而不是聚合初始化。)

于 2021-02-26T22:17:53.397 回答