5

その場で一意の変数名を作成したいと思います。

これは私のコードです:

int call(int i)
{
    return i;
}
 
#define XCAT3(a, b, c)    a ## b ## c
 
#define CALL_2(arg, place, line) int XCAT3(cl, place, line) = call(arg);
 
#define CALL_1(arg)    CALL_2(arg, __FUNCTION__, __LINE__)
 
int main(int argc, char* argv[])
{
    CALL_1(1); /* this is line 20 */
    return 0;
}

これはGCC(http://ideone.com/p4BKQ)では機能しますが、残念ながらVisualStudio2010または2012では機能しません。

エラーメッセージは次のとおりです。

test.cpp(20):エラーC2143:構文エラー:';'がありません 'function_string'の前

test.cpp(20):エラーC2143:構文エラー:';'がありません 「一定」の前

test.cpp(20):エラーC2106:'=':左のオペランドはl値でなければなりません

C ++でオンザフライの一意の変数名を作成するにはどうすればよいですか?

解決:

#define CAT2(a,b) a##b
#define CAT(a,b) CAT2(a,b)
#define UNIQUE_ID CAT(_uid_,__COUNTER__)

int main(int argc, char* argv[])
{
    int UNIQUE_ID = 1;
    int UNIQUE_ID = 2;
    return 0;
}
4

2 に答える 2

6

一意の識別子の場合、多くの実装で__COUNTER__プリプロセッサマクロが提供されます。このマクロは、使用するたびに増え続ける数に拡張されます。

#define CAT(a,b) CAT2(a,b) // force expand
#define CAT2(a,b) a##b // actually concatenate
#define UNIQUE_ID() CAT(_uid_,__COUNTER__)

auto UNIQUE_ID() = call(1); // may be _uid_0
auto UNIQUE_ID() = call(2); // may be _uid_1
于 2012-10-03T14:59:39.433 に答える
2

パラメータが終了するまでトークンの貼り付けを延期する必要がありplacelineマクロで再帰的に展開されCALL_LATER2ます。これを行うには、操作を別のマクロに移動します。の本体に表示されない##限り、そのすべての引数はマクロに対して事前にスキャンされます。##CALL_LATER2

#define XCAT3(a, b, c)    a ## b ## c
#define CALL_LATER2(fun, h, place, line) \
    auto XCAT3(calllater, place, line) = \
        call_later((fun), (h));

ただし、識別子に貼り付けることができるものではなく__FUNCTION__、文字を含む文字列に展開されるため、これでも目的の処理は実行されません。"代わりに、作成した名前を基にし__LINE__て、異なるコンパイル単位で重複が発生する可能性があるという事実が問題にならないようにする必要があります(それらが特定の関数に対してローカルである場合、それは問題ないはずです、またはそれらを置くことができます匿名の名前空間で。)

于 2012-10-02T20:29:06.860 に答える