【问题标题】:Enumerate members of a structure?枚举结构的成员?
【发布时间】:2021-09-26 00:14:11
【问题描述】:

有没有办法在 C++ 或 C 中枚举结构(结构 | 类)的成员?我需要获取成员名称、类型和值。我之前在一个变量是全局范围的小项目中使用过以下示例代码。我现在遇到的问题是需要将一组值从 GUI 复制到对象、文件和 VM 环境中。我可以创建另一个“穷人”的反射系统,或者希望有更好的东西,我还没有想到。有人有什么想法吗?

编辑:我知道 C++ 没有反射。

union variant_t {
   unsigned int  ui;
   int           i;
   double        d;
   char*         s;
};

struct pub_values_t {
   const char*      name;
   union variant_t* addr;
   char             type;  // 'I' is int; 'U' is unsigned int; 'D' is double; 'S' is string
};

#define pub_v(n,t) #n,(union variant_t*)&n,t
struct pub_values_t pub_values[] = {
   pub_v(somemember,  'D'),
   pub_v(somemember2, 'D'),
   pub_v(somemember3, 'U'),
   ...
};

const int no_of_pub_vs = sizeof(pub_values) / sizeof(struct pub_values_t);

【问题讨论】:

  • 感谢您的反馈。我知道 C++ 没有反射。
  • @Mike 如果您知道 C++ 没有反射,那么不会立即使问题变得无用吗?你怎么能在没有某种反思的情况下枚举你所要求的任何东西(内置于语言中或滚动你自己的)?
  • @lothar C++ 标准没有定义所有可以用 C++ 完成的事情。例如,在 STL 之前不是标准的字符串类。这并不意味着 C++ 程序不能使用字符串。
  • @Mike:这是一个糟糕的比较。标准库中可用的内容与语言本身中可用的内容之间存在巨大差异。 (即标准库在语言本身中实现)。 std::string 没有提供您自己无法实现的东西。反射是一个完全不同的蜡球。

标签: c++ c enumeration


【解决方案1】:

由于 C++ 没有内置反射,因此您只能获取有关结构内容的单独教学信息。

这可以通过从一种格式生成您的结构,然后您可以使用该格式来了解结构信息,或者通过解析您的 .h 文件来提取结构信息。

【讨论】:

    【解决方案2】:

    您可以在中间文件中指定您的类型并从中生成 C++ 代码,例如可以从 idl 文件生成 COM 类。生成的代码为这些类型提供反射功能。

    我为不同的项目以两种不同的方式做了类似的事情:

    • 由 Ruby 脚本解析以进行生成的自定义文件
    • 将类型定义为 C# 类型,使用 C# 的反射获取所有信息并从中生成 C++(听起来很复杂,但效果出奇的好,编写类型定义与编写 C++ 定义非常相似)

    【讨论】:

      【解决方案3】:

      最简单的方法 - 切换到 Objective-C 或 Objective-C++。该语言具有良好的内省性,并且与 C/C++ 源代码完全兼容。

      你也可以使用 m4/cog/... 从一些元描述中同时生成结构和他的描述。

      【讨论】:

        【解决方案4】:

        感觉就像您正在构建某种调试器。如果您确保在构建可执行文件时生成 pdb 文件,我认为这应该是可行的。

        不确定您希望在什么上下文中进行此枚举,但在您的程序中,您应该能够调用 Microsoft 的函数 dbghelp.dll 以从变量等中获取类型信息。(我是假设你使用的是 windows,当然可能不是这样)

        希望这有助于让您走得更远。

        干杯!

        【讨论】:

          【解决方案5】:

          Boost 有一个随时可用的 Variant 库,可能满足您的需求。

          【讨论】:

            【解决方案6】:

            显而易见,C 或 C++ 中没有反射。因此没有可靠的方法来枚举成员变量(默认情况下)。

            如果您可以控制您的数据结构,您可以尝试使用std::vector<boost::any>std::map<std::string, boost::any>,然后将所有成员变量添加到向量/映射中。

            当然,这意味着您的所有变量都可能在堆上,因此这种方法会影响性能。使用 std::map 方法,这意味着你会有一种“穷人”的反映。

            【讨论】:

              猜你喜欢
              • 2019-03-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多