8

Initially I thought I needed this, but I eventually avoided it. However, my curiosity (and appetite for knowledge, hum) make me ask:

Can a preprocessor macro, for instance in

#include "MyClass.h"

INSTANTIATE_FOO_TEMPLATE_CLASS(MyClass)

expand to another include, like in

#include "MyClass.h"

#include "FooTemplate.h"
template class FooTemplate<MyClass>;

?

4

3 に答える 3

14

それはできないと思います。これは、プリプロセッサがシングル パスであるためです。したがって、他のプリプロセッサ ディレクティブを発行することはできません。

具体的には、C99 標準 (6.10.3.4 パラグラフ 3) から:

3 結果として完全にマクロ置換された前処理トークン シーケンスは、前処理ディレクティブに似ていても、前処理ディレクティブとして処理されません。

興味深いことに、これが_Pragmac99 に単項演算子が追加された理由です。#pragmaマクロでは発行できませんでしたが、発行でき_Pragmaます。

于 2009-08-11T18:15:31.797 に答える
10

C 標準では、前処理ディレクティブについて次のように述べられています (C99 - 6.10(2) - 前処理ディレクティブ)。

前処理ディレクティブは、(変換フェーズ 4 の開始時に) # 前処理トークンで始まる一連の前処理トークンで構成されます ...

および (C99 - 6.10(7)):

特に明記しない限り、前処理ディレクティブ内の前処理トークンはマクロ展開の対象ではありません。

例:

#define EMPTY
EMPTY # include <file.h>

2 行目の一連の前処理トークンは前処理ディレクティブではありません。これは、変換フェーズ 4 の開始時に # で始まっていないためです。マクロ EMPTY が置き換えられた後でも # で始まります。

#includeしたがって、いいえ、マクロは ' ' 前処理ディレクティブに展開できません。これらのディレクティブは、変換フェーズ 4 の開始時に配置する必要があります (これらのディレクティブの処理が行われると、前処理が行われます)。マクロ展開はフェーズ 4 で発生するため、マクロはフェーズ 4 の開始時に何かを存在させることはできません。

ただし、次のことが機能することを指摘したいと思います。

#ifdef WIN32
#define PLATFORM_HEADER "platform/windows/platform.h"
#else
#define PLATFORM_HEADER "platform/linux/platform.h"

#include PLATFORM_HEADER

C 標準では次のように規定されているため (C99、6.10.2(4) - ソース ファイル インクルード):

フォームの前処理ディレクティブ

# include pp-tokens new-line

(前の 2 つの形式のいずれとも一致しない) は許可されます。ディレクティブに含まれた後の前処理トークンは、通常のテキストと同様に処理されます。(マクロ名として現在定義されている各識別子は、前処理トークンの置換リストに置き換えられます。)

于 2009-08-11T18:42:53.037 に答える
1

すべてのプリプロセッサ ディレクティブは、マクロの展開が始まる前に解釈されるため、マクロを #include ディレクティブに展開して、そのように解釈することはできません。代わりに、(誤った) C++ コードとして解釈されます。

于 2009-08-11T20:22:36.800 に答える