【问题标题】:c++ converting unknown struct to stringc ++将未知结构转换为字符串
【发布时间】:2017-06-20 12:40:30
【问题描述】:

我有一个问题。是否可以从结构中获取所有数据类型和变量名?例如:

void func(void *p){
std::cout <<  "p->type_1" << ... << "p->type_x" << std::endl;
std::cout <<  "p->name_1" << ... << "p->name_x";}

typedef struct{
int a;
char b;
float c;
}test;

test a;
func(&a); 
//There should come something like 
"int char float"
"a b c"

【问题讨论】:

标签: c++ parsing struct void


【解决方案1】:

为此,您需要支持 C++ 中的自省和运行时类型信息。有些语言内置了这个,但 C++ 没有(嗯,这还不够)。

根据您的需要,您可以构建有关struct 数据类型的信息,并将指向该信息的指针与该结构指针一起传递给您的函数。对此有用的工具可能是 typeid 运算符、offsetof 宏、typeof 宏和带有字符串化运算符 (#) 的 C 预处理器。

通过这些,您应该能够构建一个包含字段名称的数组,该数组可以识别它具有什么原始类型,以及可以在void* 中找到它的偏移量。如果您还需要支持其他 struct 类型的字段(基本上您需要将它们的字段嵌入到该结构中,或者引用它。

也就是说,可能有更好、更简单的方法来执行此操作,具体取决于您需要此输出的用途以及您对代码的控制程度以及要打印的 structs。

例如,大多数调试器可以使用特定于平台的调试元数据打印structs,因此如果您只是想改善调试体验,则可能不需要此方法(此信息通常位于单独的文件中,并且包含许多其他东西,所以不适合在调试之外使用)。

或者,如果你可以修改你得到的类(在 C++ 中类和structs 是一样的),你可以给它们一个通用的基类和一个print() 方法。然后每个struct 都会知道如何打印自己,你可以直接调用它。

如果您可以使用,可能还有其他解决方案,但这取决于您为什么需要它以及谁控制您尝试打印的类以及原因。例如。对象图序列化工具等

【讨论】:

    【解决方案2】:

    不是直接的,X-Macro 可以提供帮助,但这真的很丑:

    #include <stdio.h>
    
    #define TEST \
        X(int a;) \
        X(char b;) \
        X(float c;)
    
    typedef struct {
    #define X(x) x
        TEST
    #undef X
    } test;
    
    void print()
    {
    #define X(x) puts(#x);
        TEST
    #undef X
    }
    
    int main(void)
    {
        print();
        return 0;
    }
    

    输出:

    int a;
    char b;
    float c;
    

    【讨论】:

    • 爱 X 宏。非常有用,虽然在某些情况下有点太聪明了。
    【解决方案3】:

    无法从结构中检索。
    从变量中,你可以得到:

    int a= 5;
    cout << "a has type: " << typeid(a).name() 
    

    输出:整数

    【讨论】:

      【解决方案4】:

      如果它是一个结构,所有字段都是公共的,所以没有什么能阻止你做 std::cout a) b) a b

      【讨论】:

      • 关键是我们不知道struct 是什么类型的func。它可能不包含字段ab
      • "如果是结构,所有字段都是公共的..." 不,不是在 C++ 中。在此特定示例中,所有成员都是公共的,但这与使用的 struct 无关。 class 也可以这样做。
      • sasha 是对的,我想写的函数不知道结构的类型。我知道我可以将 void 指针转换为我需要的结构,但这不是我想要的。
      • @juanchopanza "如果它是一个结构,字段默认可见性是 public *" 更好?那么不,C++ 中没有自反性。您可以在模板函数中转换您的函数,它的作用基本相同,但如果您尝试读取或写入您将使用的类型名中不存在的字段,它将无法编译。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-13
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      • 2021-12-01
      • 2019-12-27
      • 1970-01-01
      相关资源
      最近更新 更多