2014-04-27 50 views
2

我想要一個模板類Container,使它包含的項目和它的存儲方式都變化。因此,我希望能夠創建Container<int, Vector> (或Container<int, Vector<int> >?我不確定哪一個是正確的),Container<int, ArrayList>等,其中VectorArrayList本身是模板類。模板模板在C++:<T, V<T>>

這樣做的正確方法是什麼?我知道有可能有這樣的:template <class T, template <class U> class V>,但我如何確保第二個參數使用第一個參數作爲模板中的第一個參數?

編輯:如果這之前已回答,請在此處添加問題作爲註釋。我將刪除該問題。謝謝。

回答

2

如何確保第二個參數使用第一個參數作爲模板中的第一個參數?

您以這種方式使用它。

這是一個正確的語法:

template <class T, template <class U> class V> 
class Container { 
    using contain_type = V<T>; 
}; 

但參數U是可選的,不會宣佈任何實際的模板參數。 (很像void f(int* p);相同void f(int*);,並在第一次申報的p不聲明任何實際的對象。)

所以,你也可以同樣寫:

template <class T, template <class> class V> 
class Container { 
    using contain_type = V<T>; 
}; 

很快儘管如此,您可能會遇到上述聲明中的問題:您不能將其與std::vector,std::list,std::set等等一起使用。這是因爲它們不是僅具有一個模板參數的模板。由於默認的模板參數,std::vector<int>確實是std::vector<int, std::allocator<int>>,std::set<int>std::set<int, std::less<int>, std::allocator<int>>,依此類推。

要解決這個問題,你需要第二個參數來匹配可變參數模板:

template <class T, template<class...> class V> 
class Container { 
    using contain_type = V<T>; 
}; 

這仍然只允許模板只有類型參數,但是這是一個好了很多。

現在,例如,您可以使用Container<int, std::vector>作爲類型。

1

最簡單的答案取決於以下事實:標準庫中的所有容器都有一個名爲value_type的成員typedef。因此,你可以只用一個類型參數定義類模板:

template<typename T> 
struct Container 
{ 
    typedef typename T::value_type value_type; 
}; 

每當這與標準庫中的容器實例化時,它會知道value_type並且你可以有樂趣:

::std::cout << sizeof(Container<::std::array<char, 1>>::value_type) << "\n"; // prints 1 
::std::cout << sizeof(Container<::std::vector<short>>::value_type) << "\n"; // prints 2 
::std::cout << sizeof(Container<::std::list<int>>::value_type) << "\n"; // prints 4