2016-02-12 46 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是令牌。令牌粘貼操作符用於基於其他令牌形成新的令牌。

您將不得不爲這兩個用例使用不同的宏。