2012-01-06 17 views
4

次のコードはclang 3.0を使用してコンパイルされませんが、これは間違って実行したためですか?なぜなら、C++ 11ではこれが許可されていないか、clangではサポートされていないからです。Variadicテンプレートのテンプレート引数

template<int OFFSET> 
struct A { 
    enum O { offset = OFFSET }; 
}; 

template < template <int T> class Head, typename... Tail> 
struct C : public Head<1>, private C<Tail> { }; 

int main() 
{ 
    C< A, A > c1; 

    return 0; 
} 

コンパイラエラー:

test3.cxx:99:42: error: template argument for template template parameter must be a class template or type alias template 
    struct C : public Head<1>, private C<Tail> { }; 
             ^
test3.cxx:103:15: error: use of class template A requires template arguments 
     C< A, A > c1; 
      ^
test3.cxx:94:12: note: template is declared here 
    struct A { 
     ^
2 errors generated. 
+1

'Tail'はテンプレートのパラメータパックですが、' C <> 'のインスタンス化時にパックを展開することはありません。' C <> 'はどのような型でインスタンス化されますか? – ildjarn

答えて

5

3つの問題は:

Tailはないタイプで、テンプレートの可変引数リストになることです。したがって、それは代わりに

typename... Tail 

template<int> class... Tail 

する必要があり、あなたが明示的にprivate C<Tail...>の代わりprivate C<Tail>とパラメータパックを展開する必要があります。

そしてTail...が空になったときのために、あなたは、基本ケースを実装する必要があります:

// base case 
template < template <int> class Head> 
struct C<Head> : public Head<1> { }; 

(これはクラン3.0用にコンパイルされた)

今のコードの作品全体:

template<int OFFSET> 
struct A { 
    enum O { offset = OFFSET }; 
}; 

template < template <int> class Head, template<int> class... Tail> 
struct C : public Head<1>, private C<Tail...> { }; 
template < template <int> class Head> 
struct C<Head> : public Head<1> { }; 

int main() 
{ 
    C< A, A > c1; 
    return 0; 
} 
関連する問題