0

次のコードがあるとします。

template <template <typename> class T>
class A {};

template <typename T>
class B
{
    A<B> instance;
};

int main()
{
   B<int> instance;
}

gcc 4.7.2 と gcc 4.8.0 はこのコードを正常にコンパイルしますが、icc 13.0.1 と clang 3.2 ではエラーが発生しました (clang では B ではなく ::B が必要ですが、icc ではテンプレート インスタンスの < の後に空白も必要です)。

誰が正しいですか?

私はそれについてのスレッドを見つけました (テンプレート テンプレート パラメータとして自身を参照する Template クラス? )、しかし、標準の 14.6.1/2 を理解できず、LLVM バグ 14350 ( http://www.mail- archive.com/llvmbugs@cs.uiuc.edu/msg21095.html )。それで、ここでclangとintelが間違っていますか?

4

1 に答える 1

1

14.6.1 言います:

注入されたクラス名は、テンプレート名またはタイプ名として使用できます。template-argument-listと共に使用する場合、テンプレートtemplate-parameterのテンプレート引数として使用する場合、またはフレンド クラス テンプレート宣言の精巧な型指定子の最終識別子として使用する場合は、クラス テンプレート自体を参照します。 .

「injected-class-name」は、クラスBのスコープに「注入」されたクラス テンプレート ( ) の名前です。Bつまり、クラスの定義内での非修飾名の使用を指しますB。テンプレート名が必要なコンテキストでその名前を使用する場合、つまり、明示的なテンプレート引数 ( B<int>) を使用するか、テンプレート テンプレート パラメータを取るテンプレートのテンプレート引数( ) としてA<B>使用する場合は、テンプレート自体を参照する必要があります。

だから、gccは正しいです。

<また、C++11 では、 inの後にスペースは必要ありません<::B>。セクション 2.5、パラグラフ 3 によると、入力ストリームをトークンに分割する場合:

次の 3 文字が<::で、後続の文字が or のいずれ:でもない>場合、<はそれ自体がプリプロセッサ トークンとして扱われ、代替トークンの最初の文字としては扱われません<:。(<:は別の書き方[です。)

于 2013-02-14T19:54:34.237 に答える