c ++将未知结构转换为字符串

时间:2017-02-03 07:46:38

标签: c++ parsing struct void

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

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"

4 个答案:

答案 0 :(得分: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;

答案 1 :(得分:1)

为了实现这一点,您需要支持C ++中的内省和运行时类型信息。有些语言内置了这种语言,但C ++没有(嗯,不足以达到此目的)。

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

有了这些,您应该能够构建一个包含字段名称的数组,这些数据可以标识它具有的基本类型,以及void*中可以找到的偏移量。如果您还需要支持其他struct类型的字段,则可能还需要更多工作(基本上您需要将其字段嵌入到该结构中,或引用它。

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

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

或者,如果你可以修改类(在C ++类和struct中是相同的),你可以给它们所有的公共基类和print()方法。然后每个struct都知道如何打印自己,你可以称之为。

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

答案 2 :(得分:0)

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

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

输出:int

答案 3 :(得分:-3)

如果它是一个结构,所有字段都是公共的,所以没有什么可以阻止你做std :: cout&lt;&lt; typeid(p-> a)&lt;&lt; typeid(p-> b)&lt;&lt;的std :: ENDL; std :: cout&lt;&lt; p-> a <&lt;&lt; p-> b <&lt; ENDL