Я пытаюсь обернуть голову вокруг некоторых угловых случаев с помощью унифицированной инициализации c ++ 11, и я не могу понять, почему это так:
struct Base
{
int x,y,z;
};
struct Derived : Base
{
};
static_assert (std::is_trivial<Base>::value, "Base must be trivial");
static_assert (std::is_trivial<Derived>::value, "Derived must be trivial");
Base b{1, 2, 3}; // 1) This compiles fine
Derived d{10, 20, 30}; // 2) This fails
Линия отмечена 2 терпит неудачу с «нет подходящего конструктора для инициализации Derived» сообщение как с clang 3.1
а также g++ 4.7
,
Я не могу понять, почему, в случае Derived, он пытается вызвать конструктор и не выполняет (я не знаю, как это вызвать, может быть, агрегатная инициализация?) как в случае с строкой 1).
Что-то в следующих рассуждениях не так?
А) Будучи тривиальными гарантиями, он может быть статически инициализирован.
Б) Для статической инициализации код не должен выполняться во время выполнения и, следовательно, не требуется никакого вызова конструктора
A+B
=> почему он пытается вызвать конструктор для типа, который, как он знает, тривиален?
Я очень смущен ….
Быть тривиальным не имеет ничего общего с тем, как вы можете что-то инициализировать. Важным моментом является ли ваш Derived
тип является совокупный, что не так:
§8.5.1 [dcl.init.aggr] p1
совокупный является массивом или классом (раздел 9) без пользовательских конструкторов (12.1), нет скобки или равно-инициализаторы для нестатических элементов данных (9.2), нет частных или защищенных нестатических элементов данных (пункт 11), нет базовых классов (статья 10), и нет виртуальных функций (10.3).
Только агрегаты могут быть инициализированы с помощью инициализации агрегата, поэтому инициализация списка (официальное название для унифицированной инициализации) может только попытаться найти подходящий конструктор.
Что вы можете сделать, это предоставить constexpr
конструктор, который переходит к базовому классу, и добавить default
Редактор по умолчанию:
struct Derived : Base{
Derived() = default;
constexpr Derived(int a, int b, int c) : Base{a, b, c}{}
};
Других решений пока нет …