【问题标题】:Automatically translate a set of C constants to C++ strongly typed enum自动将一组 C 常量转换为 C++ 强类型枚举
【发布时间】:2021-07-23 14:12:30
【问题描述】:

我们有一个顶级 C 库头文件,其中包含一组常量 (以及 C 函数或课程),例如:

const int32_t Sample_FooFoo = 1;
const int32_t Sample_FooBar = 2;
const int32_t Sample_BarFoo = 3;
const int32_t Sample_BarBar = 4;

int API_Function_BarbarbarFooFoo_1();
int API_Function_BarbarbarFooFoo_2();
...

为了方便起见,我们的想法是为这个头文件提供一个 C++ 包装器:即,它只是将一组常见的函数包装到类中,处理错误的异常,一切都很好。

然而,我们偶然发现的问题是如何将一组 C 常量转换为适当的强类型枚举?和上面一样应该翻译成:

enum class Sample : int32_t 
{
    FooFoo = 1,
    FooBar = 2,
    ...
};

手动执行此操作本质上违反了 DRY 范式,它不再那么漂亮和闪亮了.. 也许有一些自动的方法可以做到这一点?例如,通过编写一个 python 脚本来解析 C 头文件并将每组常量(可能经过适当注释)转换为相应的 C++ 枚举?

【问题讨论】:

  • 虽然不是特别复杂,但 C 语法已经很难用简单的脚本处理:多行 cmets 可能包含接近您想要处理的数据的数据呢?恕我直言,手动操作并不违反 DRY 原则:DRY 表示最终代码不应包含重复的块,此处不会有重复。
  • 重写代码涉及手动工作。你如何去做并不重要,重要的是最终结果。

标签: python c++ c parsing clang


【解决方案1】:

你可以使用XMacro

#define SAMPLE_ENUMS \
  X(FooFoo, 1) \
  X(FooBar, 2) \
  X(BarFoo, 3) \
  X(BarBar, 4)

#if __cplusplus

enum class Sample : int32_t 
{
  #define X(NAME,VAL) NAME = VAL,
  SAMPLE_ENUMS
  #undef X
};

#else

#define X(NAME,VAL) const int32_t Sample_## NAME = VAL;
SAMPLE_ENUMS
#undef X

#endif

我建议在 C 变体中添加 static 以避免在链接多个翻译单元时由于多个定义而出现问题。

【讨论】:

  • +1 一个优雅的想法,这绝对是内部开发代码的一种方式.. 还学习了 X-macros。然而,出于我们的目的,这不是一个选择:假设您有一个 C++ 库(比如 OpenCV)的顶级头文件,以这种神秘的方式定义常量,intelliSense 很可能在这里也不起作用。我认为唯一的方法是对头文件进行一些后处理(在初始项目配置期间),例如以某种方式从 C 变体生成 C++ 变体枚举..
猜你喜欢
  • 1970-01-01
  • 2017-10-14
  • 2019-06-09
  • 1970-01-01
  • 2020-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多