【问题标题】:Passing an enum string (not value) to a macro将枚举字符串(不是值)传递给宏
【发布时间】:2015-07-09 01:06:59
【问题描述】:

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

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?)。问题是以适当的方式将其传递给宏。

【问题讨论】:

  • 嗯,你试过了吗?
  • 请选择一种语言:C 或 C++。
  • 宏仅在编译时进行评估和扩展。如果我正确阅读了您的问题,则您要求的是在运行时确定的内容。在这种情况下,宏将不起作用。您需要另一种解决方案,例如 std::map 包含指向知道如何根据需要读取/写入各个结构字段的函数的指针。
  • 你想解决什么问题?我认为使用语言而不是宏可能有更好的方法。
  • @simon_says:你应该忘记这一点。虽然您可以在 C++ 中像 C 一样编程,但实际上不应该。即使是相似的语法也可能有细微的差异,这会使调试变得非常困难。

标签: c++ enums macros


【解决方案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;
    }
}

【讨论】:

  • 只是想知道是否有办法将一个宏的输出按原样传递给另一个宏。所以在问题的例子中,可以使用 BOOST_PP_STRINGIZE(field_1) 的输出作为参数传递给 my_macro 吗?
  • @simon_says 您可以将宏作为参数传递给另一个宏,但在这种情况下这样做没有意义。这个宏所做的就是#define BOOST_PP_STRINGIZE(x) #x,它将x 转换为"x"。您可以在宏中使用相同的资源,但将其转换为字符串不会使其神奇地工作,事实上它甚至不会编译。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 2021-07-25
    • 2021-01-16
    相关资源
    最近更新 更多