Сводная инициализация списка с другим агрегированным объектом - PullRequest
2 голосов
/ 08 марта 2019

У меня есть:

struct DisplayConfig {
    int width;
    int height;
    int colorDepth;
};

И еще один агрегат:

struct DisplayResolution {
    int width;
    int height;
};

Я бы хотел, чтобы они им понравились:

DisplayResolution resolution{1920, 1080};
DisplayConfig config{r, 32};

Что не работает.

Изменение DisplayConfig на:

struct DisplayConfig {
    DisplayResolution resolution;
    int colorDepth;
};

будет работать, но изменение DisplayConfig не вариант, также доступ к config.width больше не будет работать.

DisplayConfig{r.width, r.height, 32}; конечно работает, но синтаксис похож на:

DisplayConfig config{r, 32};

возможно?

1 Ответ

2 голосов
/ 08 марта 2019

Нет, это невозможно, учитывая ваше состояние: «изменение DisplayConfig не вариант». Класс DisplayConfig удовлетворяет условиям агрегата (в C ++ 14), так как в нем нет ни предоставленных пользователем конструкторов, ни закрытых или защищенных нестатических элементов данных, ни базовых классов, ни виртуальных функций.

При инициализации такого агрегата списком инициализаторов применяется следующее:

8.5.1 Агрегаты [dcl.init.aggr]
...
2 Когда агрегат инициализируется списком инициализаторов, элементы списка инициализаторов берутся в качестве инициализаторов для элементов агрегата , в порядке возрастания индекса или порядка элементов. Каждый член инициализируется копией из соответствующего предложения инициализатора. Если предложение-инициализатор является выражением и сужающее преобразование требуется, чтобы преобразовать выражение, программа плохо сформирована. [Примечание: Если предложение initializer само является списком инициализатора, элемент инициализируется списком, что приведет к рекурсивному применению правил в этом разделе, если элемент является агрегатом. —Конечная записка]

Так в следующем утверждении:

DisplayConfig config{r, 32};

r принимается за инициализатор первого члена DisplayConfig, который равен width. Это приводит к ошибке из-за сбоя преобразования:

error: cannot convert 'DisplayResolution' to 'int' in initialization
     DisplayConfig config{ r, 32 };
                             ^

и предупреждение, поскольку член depth класса DisplayConfig не задан при инициализаторе:

warning: missing initializer for member 'DisplayConfig::colorDepth' [-Wmissing-field-initializers]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...