2013-09-25 37 views
9

私の問題は、次のコードで再開することができます。テンプレートメソッドと、デフォルトのテンプレート引数

test-temp.C:16:47: error: invalid use of type ‘C2<T>’ as a default value for a template template-parameter 
     template <typename Ti> class Container = C2> 

それを:

template <typename T> struct C2; 

template <typename T> 
struct C1 
{ 
    template <typename Type, 
     template <typename Ti> class Container = C2> 
    void m() {} 
}; 


template <typename T> 
struct C2 
{ 
    template <typename Type = int, 
     template <typename Ti> class Container = C2> // <-- Here is the problem! 
    void m() {} 

}; 

GNUコンパイラを、バージョン4.8.1には、次のメッセージで失敗メソッドC2 :: mのデフォルトテンプレートパラメータC2を参照します。

明らかに(私の意見ですが)、コンパイラはC2<T>なし)ではなく、デフォルトパラメータとしてC2<T>を表示しています。だから、それはタイプC2<T>Containerと一致していないので、それが失敗した命令を見つけたとき。

しかし、打ち鳴らす++は、ちょうどまったく同じコードのために、罰金コンパイル!

私の質問:真実を持っているコンパイラ

  1. GNUコンパイラの現在のバージョンと同じ感覚を表現するためのいくつかの代替はありますか?

ローカルで事前に感謝

レアンドロ

+0

g ++が間違っていて、テンプレートテンプレートの名前も正しくありません。 – aaronman

答えて

9

私はクランが正しいことだと思う、およびg ++がエラーである、ドラフト標準からの引用(太字強調は私です)

14.6.1宣言された名前[temp.local]

1通常の(テンプレートではない)クラスと同様に、クラステンプレート 注射クラス名(第9項)がある。注入されたクラス名は、 テンプレート名または型名として使用できます。それはテンプレート テンプレートパラメータ用テンプレート引数として テンプレート引数リスト、と共に使用される場合、又は におけるFiの最終識別子として詳述-typespeciフレンドクラステンプレート宣言のFiのERを、それが を指しますクラステンプレート自体それ以外の場合は、テンプレート名が<で囲まれたクラス テンプレートのテンプレートパラメータ>に続いて に相当します。

あなたが提出

template <typename T> 
struct C2 
{ 
    template <typename Type = int, 
     template <typename Ti> class Container = ::C2> 
               // ^^ <-- here is the solution! 
    void m() {} 

}; 

Live ExampleにG ++ビートに::スコープ解決演算子を使用することができます。

+0

Brilliant! ...そしてタイムリーに。ありがとう! – lrleon

+0

@Irleonは助けになってうれしいです。そして、Stackoverflowへようこそ! – TemplateRex

+1

@TemplateRex私はIrleonかGCCがこれについてのバグレポートを持っているか、または作成したことを確認しましたか?それはいいですが、それは固定されていません。私は通常、bugzillaにリンクして、問題を修正したバージョンを後で確認できるようにします。 (また:+1) –

0

のでTemplateRexの答えでは14.6.1参照が、それは、テンプレートテンプレートパラメータのテンプレート引数としてXを使用するので、これを受け入れるようにG ++が正しい(とクランとVCが間違っ++ある)ことを意味するのでしょうか?

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

template< typename T > 
class X 
{ 
     friend class factory<X>; // *** 
}; 

int main() 
{ 
} 

この例では、G ++はXをクラステンプレートの名前として扱いますが、ClangとVC++はそれを注入されたクラス名として扱います。

関連する問題