Инициализирующий значение элемент std :: array? - PullRequest
2 голосов
/ 15 марта 2020

Предположим, у меня есть шаблон класса, в котором есть член std::array:

template<typename T>
class C {
public:
    C();

private:
    std::array<T, 42> a;
};

Как определить C::C так, чтобы a всегда было инициализировано значением (не инициализировано по умолчанию) )? ie так, что конструктор вызывает T() для инициализации каждого элемента a - и что, например, если T равно int, то каждый элемент a гарантированно равен нулю, а не неопределенное значение?

int main() {
   C<int> c;
   assert(c.a[13] == 0); // ignoring private for exposition
}

ОБНОВЛЕНИЕ

Дополнительная информация для потомков:

  1. std::array - это агрегатный тип с одним элементом T[N]
  2. Инициализация std::array списком инициализации - это совокупная инициализация
  3. Совокупная инициализация с пустым списком инициализации приводит к тому, что каждый элемент не инициализируется явным образом. Такие элементы инициализируются как бы путем инициализации копирования из пустого списка инициализации.
  4. Массив T[N] инициализируется копией из пустого списка инициализации. Это также совокупность, поэтому 2 и 3 применяются рекурсивно.
  5. Каждый из N элементов T[N] инициализируется копией из пустого списка инициализации.
  6. Каждый объект T копируется список инициализируется с пустым списком инициализации согласно [dcl.init.list]/3. Достигнуто последнее предложение этой цепочки, которое гласит:

В противном случае, если в списке инициализатора нет элементов, объект инициализируется значением.

и вуаля. Инициализация std::array с пустым списком инициализации {} приводит к инициализации его элементов.

1 Ответ

4 голосов
/ 15 марта 2020

Вы можете использовать встроенную инициализацию члена:

private:
    std::array<T, 42> a{};

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

C()
    : a{}
{ }
...