лязг здесь правильный. Вот сокращенный пример:
struct B {
protected:
B() { }
};
struct D : B { };
auto d = D{};
В C ++ 14 D
является , а не агрегатом, поскольку имеет базовый класс, поэтому D{}
является "нормальной" (неагрегированной) инициализацией, которая вызывает D
конструктор по умолчанию, который в свою очередь вызывает конструктор по умолчанию B
. Это нормально, потому что D
имеет доступ к конструктору B
по умолчанию.
В C ++ 17 определение агрегата было расширено - теперь разрешены базовые классы (если они не virtual
). D
теперь является агрегатом, что означает, что D{}
является агрегатной инициализацией. И в агрегатной инициализации это означает, что мы (вызывающая сторона) инициализируем все подобъекты - включая подобъект базового класса. Но мы не имеем доступ к конструктору B
(это protected
), поэтому мы не можем вызвать его, так как он некорректно сформирован.
<ч />
Не бойся, исправить легко. Используйте скобки:
auto d = D();
Это возвращает нас к вызову конструктора D
по умолчанию, как и раньше.