Как упоминалось в комментариях и как ответил @sbabbi, ответ кроется в деталях.
12.6.2 Инициализация баз и членов [class.base.init]
В конструкторе без делегирования, если данный нестатический член данных или базовый класс не обозначен идентификатором-инициализатора-mem (включая случай, когда нет списка-инициализатора-mem, потому что конструктор не имеет инициализатора ctor) и объект не является виртуальным базовым классом абстрактного класса (10.4), то
- if the entity is a non-static data member that has a brace-or-equal-initializer , the entity is initialized as specified in
8.5;
- в противном случае, если объект является анонимным объединением или вариантным членом (9.5), инициализация не выполняется;
- в противном случае объект инициализируется по умолчанию
12.6.2 Инициализация баз и членов [class.base.init]
Если данный нестатический член данных имеет как инициализатор скобок или равенства, так и инициализатор памяти, выполняется инициализация, указанная инициализатором памяти, и инициализатор скобок или равенства нестатического члена данных игнорируется. [Пример: Дано
struct A {
int i = /∗ some integer expression with side effects ∗/ ;
A(int arg) : i(arg) { }
// ...
};
конструктор A(int) просто инициализирует i значением arg, и побочные эффекты в инициализаторе скобок или равенства i не будут иметь места. — конец примера]
Таким образом, если имеется неудаляющий конструктор, инициализатор скобок или равенства игнорируется, и превалирует инициализация конструктора в члене. Таким образом, для элементов массива, для которых не указан размер, выражение становится неправильным. §12.6.2, пункт 9, делает это более явным, где мы указали, что выражение инициализатора r-значения опускается, если инициализация памяти выполняется конструктором.
Кроме того, обсуждение группы Google еще одно непоследовательное поведения в C++, дорабатывает и делает его более понятным. Это расширяет идею, объясняя, что инициализатор скобок или равенства — это прославленный способ инициализации в члене для случаев, когда инициализация внутри члена для члена не существует. В качестве примера
struct Foo {
int i[5] ={1,2,3,4,5};
int j;
Foo(): j(0) {};
}
эквивалентно
struct Foo {
int i[5];
int j;
Foo(): j(0), i{1,2,3,4,5} {};
}
но теперь мы видим, что если бы размер массива был опущен, выражение было бы некорректным.
Но, говоря это, компилятор мог бы поддерживать эту функцию для случаев, когда член не инициализируется инициализацией конструктора внутри члена, но в настоящее время ради единообразия стандарт, как и многие другие вещи, не поддерживает эту функцию.
person
Abhijit
schedule
12.04.2015
str
также может быть инициализирован в списке-инициализации-членов конструктора Foo, отбрасывая инициализатор из инициализатора в классе - person Piotr Skotnicki   schedule 12.04.2015