我该如何初始化boost::array?

14

我正在尝试理解 boost数组。可以从作者的网站轻松阅读代码

在设计理念中,作者(Nicolai M. Josuttis)提到可以使用以下两种类型的初始化。

boost::array<int,4> a = { { 1, 2, 3 } };  // Line 1
boost::array<int,4> a = { 1, 2, 3 };      // Line 2

在我使用g++(版本4.1.2)的实验中,第一行能够工作,但第二行不能。 (第二行的结果如下所示:

warning: missing braces around initializer for 'int [4]'
warning: missing initializer for member 'boost::array<int, 4ul>::elems'

不过,我的主要问题是,第一行代码是如何工作的?我尝试编写一个类似于array.hpp的类,并使用类似于第一行的语句,但是它没有起作用:-(。错误信息如下:

typedef array< unsigned int, 10 > MyArray;

MyArray b = { { 1, 2, 3 } };  // Line 74

array_test.cpp:74: error: in C++98 'b' must be initialized by constructor, not by '{...}'
array_test.cpp:74: error: no matching function for call to 'array<unsigned int, 10u>::array(<brace-enclosed initializer list>)'
array.h:16: note: candidates are: array<unsigned int, 10u>::array()
array.h:16: note:                 array<unsigned int, 10u>::array(const array<unsigned int, 10u>&)

有人能解释一下吗?第1行中是否发生了某些特定于boost的事情,我需要注意吗?


正如Potatoswatter所提到的,这仅适用于POD类型。然而值得注意的是,即将推出的C++0x规范提供了支持非POD类型的初始化列表的方法。 - Michael Anderson
3
你的类里可能有构造函数或私有字段。 - Anycorn
+1 @aaa:非常感谢。是的,我的数组(数据)在我的类中是私有的。 - Arun
2个回答

20

这是常规的大括号初始化列表:

Boost数组的定义如下:

struct array { T elems[N]; };

内部大括号用于elems数组的初始化,外部大括号用于结构体的初始化。 如果您提供自己的构造函数,则不再具有普通的数据类型,并且不能使用大括号进行初始化。
请注意,您可以没有外部大括号,但会收到警告。

+1:感谢您对内括号和外括号的解释。 - Arun
我接受这个答案,因为这个答案和同一作者对问题的评论真的帮助我解决了我的问题。 - Arun

9
标准的相关部分是§8.5.1,聚合体。
  1. 聚合体是一个没有用户声明构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条)和没有虚函数(10.3)的数组或类(第9条)。
  2. 当初始化聚合体时,初始化程序可以包含一个初始化器子句,该子句由一个用大括号括起来的逗号分隔的初始化器子句列表组成,用于聚合体的成员,按照递增的下标或成员顺序编写。如果聚合体包含子聚合体,则此规则递归地应用于子聚合体的成员。
GCC 4.1.2可能违反了第11段。

11 可以通过以下方式省略初始化程序列表中的花括号。如果初始化程序列表以左花括号开头,则随后的逗号分隔的初始化程序列表将初始化子聚合体的成员;如果有更多的初始化程序,则会出现错误。但是,如果子聚合体的初始化程序列表不以左花括号开头,则只取足够的初始化程序列表来初始化子聚合体的成员;任何剩余的初始化程序都将被留给当前子聚合体是成员的聚合体的下一个成员来初始化。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接