2017-04-23 3 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

代わりに、マクロを修正して、引数を含む文字列(明確に区切られた)を生成し、それを使用してデバッグするようにしてください。 args-inがある場合は、次のステップを呼び出すことをエミュレートできます。うまくいけば何か面白いことが起こるかもしれない...しかし多分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

あなたは本当に感謝です! –

関連する問題