Подтвердить что ты не робот

Инициализация по умолчанию std:: array?

С С++ 11 std::array, есть ли у меня гарантия того, что синтаксис std::array<T, N> x; будет по умолчанию инициализирован всеми элементами массива?

EDIT: если нет, существует ли синтаксис, который будет работать на всех массивах (включая массивы нулевого размера), чтобы инициализировать все элементы по умолчанию?

EDIT: on cppreference, описание конструктора по умолчанию говорит:

(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array 

поэтому ответ может быть да. Но я хотел бы быть уверен в этом в соответствии со стандартным или будущим стандартом.

4b9b3361

Ответ 1

По определению инициализация по умолчанию - это инициализация, которая возникает, когда другая инициализация не указана; язык С++ гарантирует, что любой объект, для которого вы не предоставляете явный инициализатор, будет инициализирован по умолчанию (С++ 11 §8.5/11). Это включает объекты типа std::array<T, N> и T[N].

Имейте в виду, что существуют типы, для которых инициализация по умолчанию не имеет значения, и оставляет значение объекта неопределенным: любой тип не-класса, не-массива (§8.5/6). Следовательно, инициализированный по умолчанию массив объектов с такими типами будет иметь неопределенное значение, например:

int plain_int;
int c_style_array[13];
std::array<int, 13> cxx_style_array;

Оба массива c-style и std::array заполняются целыми числами неопределенного значения, так же как plain_int имеет неопределенное значение.

Есть ли синтаксис, который будет работать на всех массивах (включая массивы нулевого размера), чтобы инициализировать все элементы до их значения по умолчанию?

Я предполагаю, что когда вы говорите "по умолчанию", вы действительно имеете в виду "инициализировать все элементы до T{}". Это не инициализация по умолчанию, это инициализация значения (8.5/7). Вы легко можете запросить инициализацию значений в С++ 11, указав каждому объявлению пустой инициализатор:

int plain_int{};
int c_style_array[13]{};
std::array<int, 13> cxx_style_array{};

Которая будет инициализировать все элементы массива поочередно, в результате получим plain_old_int и все члены обоих типов массивов, инициализируются до нуля.

Ответ 2

Инициализация по умолчанию - это термин из Стандарта, потенциально не означающий никакой инициализации вообще, поэтому вы, вероятно, имеете в виду нулевую инициализацию.

Описание на cppreference.com на самом деле немного вводит в заблуждение. std::array - это совокупный класс, и если тип элемента примитивен, это POD: "простые старые данные", причем семантика близко соответствует языку C. Неявно определенный конструктор std::array< int, N > является тривиальным, который абсолютно ничего не делает.

Синтаксис типа std::array< int, 3 >() или std::array< int, 3 > x{}, которые предоставляют нулевые значения, не делают этого, вызывая конструктор. Получение нулей является частью инициализации значения, указанной в С++ 11 §8.5/8:

Для инициализации объекта типа типа T означает:

- если T является классом класса (возможно, cv-qualit) без предоставленного пользователем или удаленного конструктора по умолчанию, тогда объект инициализируется нулем..., и если T имеет нетривиальный конструктор по умолчанию, объект по умолчанию -initialized;

std::array не имеет пользовательского конструктора по умолчанию, поэтому он получает нуль-инициализацию. Он имеет неявно определенный конструктор по умолчанию, но он тривиальный, поэтому он не инициализируется по умолчанию. (Но это не имеет значения, поскольку тривиальная инициализация по определению не влияет на время выполнения.)

if not, существует ли синтаксис, который будет работать на всех массивах (включая массивы нулевого размера), чтобы инициализировать все элементы до их значения по умолчанию?

Маски C-стиля и std::array являются одновременно агрегатами, а способ полностью нулевой инициализации любого агрегата - с синтаксисом = {}. Это работает с С++ 98. Обратите внимание, что массивы C-стиля не могут иметь нулевой размер и что sizeof (std::array< X, 0 >) не равно нулю.

Ответ 3

Оба T x[N]; и std::array<T, N> x; по умолчанию инициализируют каждый элемент массива.

Например, если T = std::string, каждый элемент будет пустой строкой. Если T - это класс без конструктора по умолчанию, то оба не скомпилируются. Если T = int, каждый элемент будет иметь неопределенное значение (если это объявление не находится в области пространства имен)

Ответ 4

Прежде всего, T x [N] инициализирует элементы по умолчанию, хотя инициализация по умолчанию скалярного типа T фактически ничего не делает. Вышеупомянутое также относится к std:: array x. Я думаю, что вам нужна инициализация списка.