Как инициализировать boost:: array?

Я пытаюсь понять массив boost. code можно легко читать с сайта автора.

В обосновании проекта автор (Николай М. Йосуттис) отметил, что возможны следующие два типа инициализации.

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

В моем эксперименте с g++ (версия 4.1.2) работает строка 1, но строка 2 - нет. (Строка 2 дает следующее:

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

)

Тем не менее, мой главный вопрос: как работает Line 1? Я попытался написать класс, похожий на array.hpp, и использовать инструкцию типа Line 1, но это не сработало:-( Ошибка:

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, о которой я должен знать?

Ответы

Ответ 1

это регулярный список инициализации скобок:

Массив усиления определяется следующим образом:

struct array { T elems[N]; };

внутренняя скобка предназначена для инициализации массива элем., outear brace - для инициализации структуры. Если вы предоставляете свой собственный конструктор, у вас больше нет простого старого типа данных, который невозможно инициализировать с помощью скобки

обратите внимание, что вы можете обойтись без внешней скобки, но вы получите предупреждение

Ответ 2

Соответствующий раздел стандарта - это §8.5.1, агрегаты.

  • Агрегат - это массив или класс (раздел 9) без объявления пользователем конструкторы (12.1), нет частных или защищенные нестатические элементы данных (пункт 11), нет базовых классов (пункт 10) и нет виртуальных функций (10.3).
  • Когда агрегат инициализируется, инициализатор может содержать Инициализатор-предложение, состоящее из список, разделенный запятыми элементов-инициализаторов для членов совокупности, написанной в увеличивая индекс или порядок членов. Если совокупность содержит subaggregates, это правило применяется рекурсивно к членам субагрегата.

GCC 4.1.2 может нарушать пункт 11.

11 Скобки можно отбросить в initializer-list следующим образом. Если Список инициализаторов начинается с левого скобки, то последующие список инициализаторов, разделенных запятыми инициализирует членов subaggregate; это ошибочно для там будет больше инициализаторов, чем члены. Если, однако, список инициализаторов для субагрегата не начинается с левой скобки, затем только достаточно инициализаторов из списка для инициализации членов субагрегат; любой оставшийся инициализаторы оставляются для инициализации следующий член совокупности который представляет собой текущий субрегистр член.