Равномерная инициализация производного класса с тривиальным ctor

Я пытаюсь обернуть голову вокруг некоторых угловых случаев с помощью унифицированной инициализации 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 => почему он пытается вызвать конструктор для типа, который, как он знает, тривиален?

Я очень смущен ….

8

Решение

Быть тривиальным не имеет ничего общего с тем, как вы можете что-то инициализировать. Важным моментом является ли ваш 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}{}
};
11

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]