Статически инициализировать вложенные структуры C ++ с именованными метками, используя g ++ - PullRequest
0 голосов
/ 31 января 2020

Я импортирую / портирую существующий C код на C ++. Я надеюсь внести как можно меньше изменений в существующее тело кода, чтобы свести к минимуму предварительную проверку существующего кода. Этот код использует stati c именованную инициализацию вложенных структур. Для быстрого выдуманного примера:

Car car =
{
  .color = RED,
  .tire.tread = OLD,
  .tire.diameter = 27.106,
  .tire.material.type = RUBBER,
  .tire.material.density = 700,
};

Я понял, что они называются назначенными инициализаторами .

Я узнал о инициализаторах GNU , но я Я не понял, как реализовать иерархию с ним.

Я читал, что обозначенные инициализаторы поддерживаются в g ++ с включенным c ++ 11 , но это, похоже, не работает для меня .

Код, который я портирую, имеет страницы инициализации с глубиной иерархии не менее четырех уровней. Поэтому я пытаюсь найти простое преобразование, которое не слишком связано с этим.

Я ищу одно из следующих возможных решений:

  • Как включить назначенные инициализаторы C99
  • Как сформулировать иерархическую инициализацию стиля GNU
  • Что такое эквивалентный C ++ способ сделать это, который не был бы подвержен ошибкам при описании войны и мира.
  • Очевидное решение, которое у меня есть не думал о

Я использую версию G ++

g++.exe (i686-posix-dwarf-rev0, Built by MinGW-W64 project) 8.1.0

1 Ответ

0 голосов
/ 31 января 2020

Использование таких вложенных обозначенных инициализаторов кажется чем-то вроде крайнего случая. Следующее работает как в clang-cl (в Visual Studio 2019), так и в собственном компиляторе MSVC (но последний только с опцией /std:c++latest, которая использует черновой стандарт C ++ 20):

struct inner {
    int x, y;
    double z;
};
struct outer {
    char a;
    double b;
    inner c;
};

outer my_outer = { .a = 'a', .b = 1.2, .c = { .x = 3, .y = 4, .z = 5.6 } };

При clang-cl инициализатор может быть сокращен до следующей формы:

outer my_outer = { .a = 'a', .b = 1.2, .c.x = 3, .c.y = 4, .c.z = 5.6 };

, но MSVC жалуется в этом случае, с:

ошибка C7558: доступ к вложенным элементам не разрешен в стандартных инициализаторах C ++; используйте вложенный список инициализаторов

Итак, для вашего примера вы можете попробовать это:

Car car =
{
  .color = RED,
  .tire = {
     .tread = OLD,
     .diameter = 27.106,
     .material.type = RUBBER,
     .material.density = 700,
   }
};

Есть полезное "обсуждение" topi c в cppreference , причем эта часть примечательна:

... каждый указатель должен называть прямой нестатический c элемент данных T, и все указатели, используемые в выражении, должны появляться в в том же порядке, что и данные членов T.

...