2016-02-12 87 views
1

假设我有两个具有相同成员变量但不同“前缀”的结构。一个在命名空间中,另一个以某个标记作为前缀。将带有“::”的标记作为C/C++宏的参数传递

我想写一个宏来对这些结构进行相同的操作,这些结构接受不同的前缀作为输入。我尝试这样做:

#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::);

有没有办法在一个优雅的方式来接受两个输入,并与“富”将它们连接起来,以改写这个宏?我尝试过预处理B ::连接“B”和双冒号。我也尝试将Prefix ## foo更改为Prefix foo,但之后调用GET_BAR(A__)会导致编译错误。

回答

1

很难体会我想出了断章取义的解决方案,但在这里它是:

#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); 
} 

基本上,通过级联功能,而不是标记本身。

1

::foo不是预处理令牌。 ::foo是令牌。令牌粘贴操作符用于基于其他令牌形成新的令牌。

您将不得不为这两个用例使用不同的宏。