将枚举字符串(非值)传递给宏

时间:2015-07-09 01:06:59

标签: c++ enums macros

所以我有这个查询,其中说我有一个enum和一个看起来像这样的结构,

enum fields {
   field_1,
   field_2
};

struct my_struct {
    int field_1;
    int field_2;
};

我的具体需求是,给定具有结构成员名称的字节(field_1,field_2等),我应该能够生成一个宏,可以将结构成员设置为给定值。

#define my_macro (__a, __field) \
__a.__field = 1;

有没有办法像这样调用my_macro:

struct my_struct b;
/* extract members of enum as string literals  */
my_macro(b, /*field name from the enum */);

很少有其他帖子详细介绍了boost宏的使用,这有助于我将枚举成员提取为字符串(How to convert an enum type variable to a string?)。问题在于以适当的方式将其传递给宏。

2 个答案:

答案 0 :(得分:1)

它应该按照它的方式工作。宏在编译之前被处理,而代码仍然是代码,它们导致代码生成。

您的宏#define my_macro(__a, __field) __a.__field = 1;会导致my_macro(x, y)等任何条目在传递给编译器之前转换为x.y = 1;

如果您执行my_macro(1+1, "test")之类的操作,它将生成代码1+1."test" = 1;并将创建编译错误。这是多么简单的宏。

这就是为什么宏参数通常被()包围以确保它按照预期的方式工作,如果你不做这样的事情就会发生:

#define div_by_100(a) a / 100

printf("%d\n", div_by_100(1000)); // will print 10
printf("%d\n", div_by_100(500 + 500)); // will print 505

这是因为在解析宏之后,在编译时解决了操作顺序。

请注意,由于宏在编译之前已经解析,因此它们不是运行时解决方案。如果代码中未显示此enum值,则宏根本不会帮助您。您必须编写一个路由函数,该函数将根据给出的enum值为该类/结构的每个成员分配一个值。例如:

void route(struct farm* s, enum animals e)
{
    switch (e)
    {
        case cow:
            s->cow = 1;
            break;
        case duck:
            s->duck = 1;
            break;
        case horse:
            s->horse = 1;
            break;
        case goat:
            s->goat = 1;
            break;
    }
}

答案 1 :(得分:0)

这取决于将枚举转换为字符串的机制的工作方式。只要该机制仍然是由预处理器替换的宏,您的宏就应该工作。这就是问题所在。否则你的宏应该正常工作。