web-dev-qa-db-ja.com

貼り付けにより、無効な処理トークン「。」が形成されました。

タイプに基づいて適切なオブジェクトを呼び出すためにマクロを使用しようとしています。

#define DELEGATE_FUNC(FuncName, kind, paramPtr)         \
    if (kind == 1) {                                    \
        return PolicyObject1.##FuncName(paramPtr);      \
    }                                                   \
    else {                                              \
        return PolicyObject2.##FuncName(paramPtr);      \
    }                                                   \
    return 0;                                           \

(PolicyObject1とPolicyObject2は2つの静的オブジェクトです。)マクロを使用する場合、たとえば、.

DELEGATE_FUNC(ProcessPreCreate、1、null_ptr);

VS 2015では正常にコンパイルされますが、LLVMでエラーが発生します「貼り付けにより無効な処理トークン '.ProcessPreCreate'が形成されました」

私はいくつかの投稿を探して見つけ、それをある程度まで理解しました-間接参照の2倍のレベルが必要です。 マクロに2層の間接参照が必要なのはなぜですか?

しかし、私はこれらの2層のマクロを定義することができません、誰か助けてもらえますか?

(デザイン面での議論は脇に置いてください)

ありがとう

9
Nitesh

コンパイラがC++ファイルを読み取るとき、最初のステップの1つは、ファイルを識別子、文字列リテラル、数値、句読点などのトークンに分割することです。Cプリプロセッサはこれらで動作しますトークンではなくテキスト。 _##_演算子は、トークンを接着します。だから、例えば、あなたが持っているなら

_#define triple(foo) foo##3
_

次に、triple(x)は識別子_x3_を取得し、triple(12)は整数_123_を取得し、triple(.)は浮動小数点数を取得します_.3_。

ただし、持っているのは_.##FuncName_です。ここで、FuncNameProcessPreCreateです。これにより、単一のトークン_.ProcessPreCreate_が作成されますが、これは有効なC++トークンではありません。マクロではなく直接_PolicyObject1.ProcessPreCreate_を入力した場合は、_PolicyObject1_、_._、およびProcessPreCreateの3つのトークンにトークン化されます。これは、有効なC++出力を提供するためにマクロが生成する必要があるものです。

これを行うには、単に_##_を削除します。 _._をFuncNameに接着する必要はありません。これらは、別個のトークンであるためです。これを確認するには、_._とメンバー名の間にスペースを入れることができます。それでも問題なくコンパイルされます。それらは別々のトークンであるため、一緒に接着するべきではなく、接着することもできません。

20
Daniel H

「##」を削除します。

#define DELEGATE_FUNC(FuncName, kind, paramPtr)     \
if (kind == 1) {                                    \
    return PolicyObject1.FuncName(paramPtr);        \
}                                                   \
else {                                              \
    return PolicyObject2.FuncName(paramPtr);        \
}                                                   \
return 0;                                           \
1
shede333