Как инициализировать 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; это ошибочно для там будет больше инициализаторов, чем члены. Если, однако, список инициализаторов для субагрегата не начинается с левой скобки, затем только достаточно инициализаторов из списка для инициализации членов субагрегат; любой оставшийся инициализаторы оставляются для инициализации следующий член совокупности который представляет собой текущий субрегистр член.