(Все приведенные ниже ссылки на стандарты ISO относятся к N4659: рабочий проект после выпуска Kona за март 2017 г. / DIS C ++ 17 )
Согласно [class.base.init] / 9 , член mya
из b
, который имеет тип a
, инициализируется по умолчанию, но a
определяет нет конструктора по умолчанию:
В конструктор без делегирования, если данный потенциально сконструированный подобъект не обозначен идентификатором mem-initializer-id (включая случай, когда нет mem-initializer-list , потому что конструктор не имеет ctor-initializer), тогда
- (9.1) , если объект нестатический c элемент данных, который имеет инициализатор члена по умолчанию [...] объект инициализируется из его инициализатора члена по умолчанию , как указано в [dcl.init];
- (9.2) в противном случае, если сущность является анонимным объединением или вариантным членом ([class.union.anon]), инициализация не выполняется;
- (9.3) в противном случае, сущность инициализируется по умолчанию.
Здесь, поскольку mya
не объявляется вместе с инициализатором члена по умолчанию, * 1045 Применяется * [class.base.init] /9.3.
Пример [class.base.init] / 9 охватывает даже этот конкретный случай:
[...] [Пример:
struct A {
A();
};
struct B {
B(int);
};
struct C {
C() { } // initializes members as follows:
A a; // OK: calls A::A()
const B b; // error: B has no default constructor
int i; // OK: i has indeterminate value
int j = 5; // OK: j has the value 5
};
- конечный пример]
Вы можете решить эту проблему, предоставив инициализатор члена по умолчанию для mya
, таким образом, что [class.base.init] /9.1 применяет
class b {
a mya{42}; // default member initializer
int j;
public:
b(int);
};
или используйте список инициализаторов членов в определении конструктора b
; b::b(int)
, так что применяется [class.base.init] / 7 :
Список-выражений или список-инициализации в фигурных скобках в инициализаторе памяти используется для инициализировать назначенный подобъект (или, в случае делегирующего конструктора, полный объект класса) в соответствии с правилами инициализации [dcl.init] для прямой инициализации. [Пример:
struct B1 { B1(int); /* ... */ };
struct B2 { B2(int); /* ... */ };
struct D : B1, B2 {
D(int);
B1 b;
const int c;
};
D::D(int a) : B2(a+1), B1(a+2), c(a+3), b(a+4) { /* ... */ }
D d(10);
- конечный пример] [...]
, таким образом, прямая инициализация элемента mya
:
b::b(int i2) : mya(i2) {
// ^^^^^^^- member initializer list
j=2*i2;
}