将带有“::”的标记作为参数传递给 C/C++ 宏

Pass a token with "::" as argument to C/C++ macro

假设我有两个具有相同成员变量但不同 "prefixes" 的结构。一个在命名空间中,另一个以特定标记为前缀。

我想编写一个宏来对这些接受不同前缀作为输入的结构执行相同的操作。我试过这个:

#include <cstdio>

struct A__foo_
{
  int bar;
} typedef A__foo;

namespace B {
  struct foo {
    int bar;
  };
}

#define GET_BAR(Prefix)\
  { \
    Prefix ## foo my_foo;\
    printf("Bar is: %d", my_foo.bar);\
  }

int main(int argc, char ** argv) {
  GET_BAR(A__);
  GET_BAR(B::);
}

我得到这个编译器错误:

macros_example.cpp:22:7: error: pasting formed '::foo', an invalid preprocessing token GET_BAR(B::);

有没有办法以优雅的方式重写此宏以接受两个输入并将它们与 "foo" 连接起来?我已经尝试通过连接 "B" 和双冒号来预处理 B:: 。我也试过将 Prefix ## foo 更改为简单的 Prefix foo 但随后调用 GET_BAR(A__) 会导致编译错误。

::foo 不是预处理标记。 ::foo 是标记。 token-pasting operator 用于根据其他token形成一个新的token。

对于这两个用例,您必须使用不同的宏。

很难理解我断章取义的解决方案,但这里是:

#define CONCATENATE_A(X) A__ ## X
#define CONCATENATE_B(X) B:: X

#define GET_BAR(CONCATENATE)\
  { \
    CONCATENATE(foo) my_foo;\
    printf("Bar is: %d", my_foo.bar);\
  }

int main(int argc, char ** argv) {
  GET_BAR(CONCATENATE_A);
  GET_BAR(CONCATENATE_B);
}

基本上,传递一个连接函数而不是标记本身。