6

プリプロセッサ マクロを使用して特定のプレフィックスを他のマクロに追加するかなり一般的なコードがあります。これは何が起こるかの非常に単純化された例です:

#define MY_VAR(x) prefix_##x

「prefix_」は実際には別の場所で定義されているため、ファイルが含まれるたびに異なります。それはうまく機能しますが、トークンの1つが存在しない場合にスキップしたいコードがいくつかありますが、これは機能しません:

#if defined MY_VAR(hello)

私が展開したいのはこれです:

#ifdef prefix_hello

しかし、私は方法を理解できません。展開を行うには MY_VAR() マクロを使用する必要があるため、名前をハードコードすることはできません。(実際には、いくつかのテストコード用です。一連のクラスをテストするたびに、同じコードが異なるプレフィックスで含まれています。いくつかのクラスについては、いくつかのテストをスキップしたいと思います。)

これは C++ プリプロセッサで可能ですか?

アップデート:

問題をさらに実証するためのセミコンパイル可能なコードを次に示します: (下のコメントに押し込まないようにするため)

#define PREFIX hello

#define DO_COMBINE(p, x)  p ## _ ## x
#define COMBINE(p, x)     DO_COMBINE(p, x)
#define MY_VAR(x)         COMBINE(PREFIX, x)

// MY_VAR(test) should evaluate to hello_test

#define hello_test "blah blah"

// This doesn't work
#ifdef MY_VAR(test)
  printf("%s\n", MY_VAR(test));
#endif
4

3 に答える 3

3

あなたのプログラムには、この質問が説明する以上のものがありますか? ディレクティブ

#define MY_VAR(x) prefix_##x

プリプロセッサ識別子を 1 つだけ定義します。呼び出し

blah ^&* blah MY_VAR(hello) bleh <>? bleh

プリプロセッサの一方の端に入り、何も定義せずにもう一方の端から出てきます。

他の魔法が起こらなければ、前のソース コードの過程でどの引数がどのマクロに渡されたかをプリプロセッサが記憶することは期待できません。

次のようなことができます

#define prefix_test 1
#if MY_VAR(test) == 1
#undef prefix_test // optional, "be clean"
...
#endif
#undef prefix_test

プレフィックスが現在特定の値を持っているかどうかを照会しますprefix_。(未定義の識別子はゼロに置き換えられます。)

于 2010-04-24T07:37:52.520 に答える
2

プリプロセッサがそれ以上カットしないレベルに到達したと思います。それは本当に単純な考え方です。代わりにテンプレートの使用を検討しましたか? (もちろん、それらがあなたの問題にとって意味があると仮定して。)

于 2010-04-24T07:07:24.023 に答える
0

これは、更新された質問への回答です。可能な hello_test ごとに、#define hello_test "blah blah" の可能性の後に次の行を追加します。

#ifndef hello_test
#define hello_test (char*)0
#endif

次に、テストを次のように変更します。

if (MY_VAR(test))
    printf("%s\n", MY_VAR(test));

または、代わりに、すべての #define ..."blah blah" の前に、次の行を追加します。

static const char * const MY_VAR(test);

MY_VAR と test のすべての可能な値。これにより、「hello_test」のハードコーディングが回避されます。(ここでの 2 番目の const は、gcc 警告を削除します: 'hello_test' defined but not used.)

于 2010-05-03T01:33:26.600 に答える