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

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

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

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

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

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

4 ответов


по определению инициализация по умолчанию-это инициализация, которая происходит, когда никакая другая инициализация не указана; язык C++ гарантирует вам, что любой объект, для которого вам не дают явного инициализатора будут инициализированы по умолчанию (C++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-стиля, так и std::array заполняются целыми числами неопределенного значения, так же как plain_int имеет неопределенное значение.

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

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

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

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


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

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

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

значение-инициализировать объект типа T означает:

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

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

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

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


и T x[N]; и std::array<T, N> x; default-инициализировать каждый элемент массива.

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


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