【问题标题】:Statically initialize nested C++ structures with named labels using g++使用 g++ 静态初始化具有命名标签的嵌套 C++ 结构
【发布时间】:2020-01-31 15:19:12
【问题描述】:

我正在将现有 C 代码导入/移植到 C++。我希望对现有代码体进行尽可能少的更改,以最大程度地减少对现有代码的干扰。 此代码使用嵌套结构的静态命名初始化。快速编造的例子:

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

我发现these are called designated initializers

我了解了GNU initializers,但我还没有弄清楚如何用它来实现层次结构。

我读到了designated initializers are supported in g++ with c++11 enabled,但这似乎对我不起作用。

我要移植的代码有初始化页面,至少有四层深度。因此,我正在尝试寻找一种不涉及太多的简单转换。

我正在寻找以下可能的解决方案之一:

  • 如何启用 C99 指定初始化程序
  • 如何制定分层 GNU 样式初始化
  • 什么是 C++ 等效方法来执行此操作,这样在转录战争与和平时不会出错。
  • 我没想到的明显解决方案

我用的是g++版本

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

【问题讨论】:

  • 我也试过 -std=c++2a 这也会导致错误:expected primary-expression before '.'令牌

标签: c++ g++


【解决方案1】:

使用这种嵌套指定的初始化器似乎是一种边缘情况。以下适用于 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,
   }
};

topic on cppreference 有一个有用的“讨论”,这部分值得注意:

...每个指示符必须命名 T 的直接非静态数据成员,并且 表达式中使用的所有指示符必须以相同的顺序出现 作为 T 的数据成员。

【讨论】:

  • The following works in .... 并在 gcc9.2 中使用-std=c++2a
  • 我试试gcc9.2 c++2a
  • 用 -std=c++2a 回到 gcc8.1 看起来它也支持多括号格式而不是多点内联格式
猜你喜欢
  • 2011-08-13
  • 2015-01-08
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多