2017-04-23 18 views
4

我想在C++中爲新的std::optional<T>創建匹配機制。我已經寫了下面的宏:C++宏只適用於預處理爲文件

#define EXPAND(x) x 
#define CAT_(x, y) x##y 
#define CAT(x, y) CAT_(EXPAND(x), EXPAND(y)) 
#define if_opt__(xalt, bval, x, y) \ 
auto xalt = y;      \ 
bool bval = true;     \ 
if (xalt.has_value())    \ 
for (auto x = xalt.value(); bval; bval = false) 
#define if_opt_(xalt, x, y) if_opt__(xalt, CAT(xalt, _b), x, y) 
#define if_opt(x, y) if_opt_(CAT(x, __LINE__), x, y) 

而且我已經創建了下面的示例程序是:

std::optional<int> get(int a) { 
    if (a < 0) { 
     return {}; 
    } 
    return a; 
} 

int main(void) { 
    if_opt(a, get(0)) { 
     std::cout << "optional matched!" << std::endl; 
    } 
    return 0; 
} 

然而,當我試圖編譯程序,我得到這樣的「重定義錯誤;不同的基本類型'。然後我將它預處理成一個文件,複製結果並編譯並工作得很好。宏評估爲:

auto a24 = get(0); 
bool a24_b = true; 
if (a24.has_value()) 
    for (auto a = a24.value(); a24_b; a24_b = false) { 
     std::cout << "optional matched!" << std::endl; 
    } 

爲什麼不使用宏本身進行編譯?我正在使用MSVC。

+0

將宏修改爲生成一個包含它們的參數的字符串(明確定界)並使用它進行調試。如果你有參與,你可以模仿調用下一步。希望有趣的事情發生......但也許msvc只是壞了。 – Yakk

回答

2

CAT宏執行額外的擴展應予以糾正的方法:

//#define EXPAND(x) x // not needed 
#define CAT_(x, y) x##y 
#define CAT(x, y) CAT_(x, y) 

當它被在某個時候擴大它產生表達EXPAND(x)##EXPAND(y)打破進一步擴大爲##只能用普通令牌和韓元工作甚至不會嘗試擴大EXPAND

爲什麼它預處理文件時工作?可能是因爲VS有非常花哨的(和不符合)處理的東西。即使對文件進行預處理,Gcc也會爲您提供更好的診斷功能。

+0

你是完全正確的,謝謝! –