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

时间:2016-09-05 08:08:38

标签: c++ initialization aggregate c++14 declaration

为什么我不能像这样对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 }
   };
}

这样做我收到错误:

  

错误: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 } 
};

相比之下,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}};

2 个答案:

答案 0 :(得分:7)

在此声明和初始化中

   std::array<Point, 3> m_points { 
      { 1.0f, 1.0f }, 
      { 2.0f, 2.0f }, 
      { 3.0f, 3.0f }
   };

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

改为写

   std::array<Point, 3> m_points {
      { 
      { 1.0f, 1.0f }, 
      { 2.0f, 2.0f }, 
      { 3.0f, 3.0f }
      }
   };

在第二种情况下

std::array<Point, 3> m_points { 
   Point{ 1.0f, 1.0f }, 
   Point{ 2.0f, 2.0f }, 
   Point{ 3.0f, 3.0f } 
};

每个初始值设定项被顺序视为内部聚合的下一个元素的初始值。

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

#include <iostream>

struct array
{
    int a[10];
};

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

    return 0;
}

编译器发出错误,如

prog.cpp:14:33: error: too many initializers for 'array'
  array a = { { 0, 0 }, { 1, 1 } };
                                 ^

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

答案 1 :(得分:2)

与其他标准容器(如std::arraystd::vector不同,

std::map没有明确定义的构造函数,只有自动提供的构造函数。使用std::vector,编译器将尝试将表达式与每个可用构造函数和

之类的构造进行匹配
std::vecor<Point> m_points { {1.0f,1.0f}, {2.0f,2.0f}, {3.0f,3.0f} };

找到与构造函数

的匹配项
std::vector::vector(initializer_list<T>, const Allocator& = Allocator() );

但是对于std::array,它必须使用底层数组的聚合初始化(在您的情况下为Point[3]),因此您的构造不匹配。要使其工作,您必须添加另一对大括号

std::array<Point, 3> m_points { 
  { { 1.0f, 1.0f },
    { 2.0f, 2.0f }, 
    { 3.0f, 3.0f } }
};