为什么我不能像这样对std :: array进行脱盐?

Nar*_*rek 6 c++ aggregate initialization declaration c++14

为什么我不能像这样对std :: array进行脱盐?

#include <array>

struct Point
{
    float x;
    float y;
};

int main()
{
   std::array<Point, 3> m_points { 
      { 1.0f, 1.0f }, 
      { 2.0f, 2.0f }, 
      { 3.0f, 3.0f }
   };
}
Run Code Online (Sandbox Code Playgroud)

这样做我得到错误:

错误:初始化程序太多了 std::array<Point, 3ul>

但它的工作原理如下:

std::array<Point, 3> m_points { 
   Point{ 1.0f, 1.0f }, 
   Point{ 2.0f, 2.0f }, 
   Point{ 3.0f, 3.0f } 
};
Run Code Online (Sandbox Code Playgroud)

相比之下,std::map可以使用以下两种方式初始化:

   std::map<int, int> m1 {std::pair<int, int>{1,2}, std::pair<int, int>{3,4}}; 
   std::map<int, int> m2 {{1,2}, {3,4}};
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 6

在此声明和初始化中

   std::array<Point, 3> m_points { 
      { 1.0f, 1.0f }, 
      { 2.0f, 2.0f }, 
      { 3.0f, 3.0f }
   };
Run Code Online (Sandbox Code Playgroud)

编译器将大括号中的第一个初始化程序视为整个数组(内部聚合)的初始化程序.std::array是包含另一个聚合的聚合.

改为写

   std::array<Point, 3> m_points {
      { 
      { 1.0f, 1.0f }, 
      { 2.0f, 2.0f }, 
      { 3.0f, 3.0f }
      }
   };
Run Code Online (Sandbox Code Playgroud)

在第二种情况下

std::array<Point, 3> m_points { 
   Point{ 1.0f, 1.0f }, 
   Point{ 2.0f, 2.0f }, 
   Point{ 3.0f, 3.0f } 
};
Run Code Online (Sandbox Code Playgroud)

每个初始化程序被顺序地视为内部聚合的下一个元素的初始化程序.

考虑这个简单的示范程序.

#include <iostream>

struct array
{
    int a[10];
};

int main()
{
    array a = { { 0, 0 }, { 1, 1 } };

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器发出错误信息

prog.cpp:14:33: error: too many initializers for 'array'
  array a = { { 0, 0 }, { 1, 1 } };
                                 ^
Run Code Online (Sandbox Code Playgroud)

这就是决定它{ 0, 0 }是内部数组(内部聚合)的初始化器.因此,大括号中的下一个初始化程序在外部聚合(结构)中没有相应的数据成员.