2012-11-16 69 views
7

我有可變參數模板模板的問題:模板的模板語法問題

  template <typename T> class A { }; 
      template< template <typename> class T> class B { }; 
      template <template <typename> class T, typename parm> class C { typedef T<parm> type; }; 
      template <typename... types> class D { }; 
      template <template <typename...> class T, typename ... parms> class E { typedef T<parms...> type; }; 

      // How to pass list in list?? 
      template < template <typename...> class ...T, ???> 
      class F 
      { 
      }; 

首先,通過一個類型模板,沒有問題:

  A<int> a; //ok 

現在,我想從B創建實例,但沒有辦法通過模板模板參數:

  B<A> b; // ok, but no chance to submit <int> inside A! 

所以我必須擴展pa rameter列表:

  C<A, int> c; // ok, this transport int as parm into A 

現在我用標準的方式可變參數模板玩:

  D<> d1; // ok 
      D<int, float, double> d2; //ok 

傳遞參數到一個可變部分,也是兩岸前鋒:

  E<D> e1; //ok 
      E<D, double, float, int> e2; //ok 

但是:如果我想有一個列表的清單,我發現沒有語法,我會使 參數列表通過類型列表。我的意圖是這樣的。而且上面的例子顯示B<A<int>> b;是一個錯誤!下面這個例子不能工作:-(

  F< D< int, float>, D< int>, D <float, float, float> > f; 

我的目標是通過模板特解開列表清單。任何提示?

我的解決方案後,我明白這個問題。謝謝!

現在,我可以展開我的可變參數模板模板,如下例所示:簡單的問題是,我等待模板類而不是簡單類型,有時候,解決方案可以非常簡單:-)

那是我現在的工作結果:

template <typename ... > class D; 

    template <typename Head, typename... types> 
    class D<Head, types...> 
    { 
     public: 
      static void Do() { cout << "AnyType" << endl; D<types...>::Do(); } 
    }; 

    template<> 
    class D<> 
    { 
     public: 
      static void Do() { cout << "End of D" << endl; } 
    }; 

    template < typename ...T> class H; 

    template < typename Head, typename ...T> 
    class H<Head, T...> 
    { 
     public: 
      static void Do() 
      { 
      cout << "unroll H" << endl; 
      cout << "Subtype " << endl; 
      Head::Do(); 
      H<T...>::Do(); 
      } 
    }; 

    template <> 
    class H<> 
    { 
     public: 
      static void Do() { cout << "End of H" << endl; } 
    }; 


    int main() 
    { 
     H< D<int,int,int>, D<float, double, int> >::Do(); 
     return 0; 
    } 

回答

2

您可以通過專業化同時解開一個可變參數的專業化:

template<typename...> struct S; 
template<> struct S<> { constexpr static int n = 0; }; 
template<template<typename...> class T, typename... Us, typename... Vs> 
struct S<T<Us...>, Vs...> { 
    constexpr static int n = sizeof...(Us) + S<Vs...>::n; 
}; 

template<typename...> struct D {}; 

#include <iostream> 
int main() { 
    std::cout << S<D<int, int, int>, D<int, int>, D<int>>::n << '\n'; // prints 6 
} 
+0

謝謝,你的回答打開了我的眼睛。我把我的最終解決方案放在我的問題上。希望這可以幫助別人。 – Klaus

1

像這樣:

template < template <typename...> class ...T > 
class F 
{ 
}; 
int main() 
{ 
    F< D, D > f; 
} 

那麼,F的期望是一個可變參數模板類,這需要另一個可變參數模板類,因爲它的參數。

您無法展開模板類參數參數的參數。如果您專門將您傳遞的模板類作爲參數,那麼您將獲得專用版本。

此:

F< D< int, float>, D< int>, D <float, float, float> > f; 

不起作用,由於f預計可變參數模板類,以可變參數模板類的類型和D< int, float>不是一個模板了(它是一個具體的類)。

+0

@克勞斯你寫道:'沒有機會提交裏面!!你可以在A這個'typedef A type'中做,並且在B中用它作爲'typename A :: type',但是你不能在一個可變參數模板中做到這點(這是不能做到的:'typedef typename ... types' ) –

+0

似乎是我完全錯誤的方式和可變模板模板不是解決方案。有沒有其他的方式來獲得所需的功能?很容易得到一個可以通過專業化擴展的列表。我仍然希望通過列表清單也有辦法解決這些問題。任何暗示都很好!你能給我一個你最後評論中的含義的實例嗎? – Klaus