示例,我想专门化一个类,使其成为一个stl容器的成员变量,比如一个向量或一个列表,所以我需要这样的东西:
template <class CollectionType, class ItemType>
class Test
{
public:
CollectionType<ItemType> m_collection;
};
所以我能做到:
Test t = Test<vector, int>();
t.m_collection<vector<int>> = vector<int>();
但这会产生
test.cpp:12: error: `CollectionType' is not a template
答案 0 :(得分:14)
您想要的是模板模板参数:
template <template <typename> class CollectionType, class ItemType>
class Test
{
public:
CollectionType<ItemType> m_collection;
};
我们在此处所做的是指定第一个模板参数,即CollectionType
,是一个类型模板。因此,Test
只能使用本身就是模板的类型进行实例化。
但是,正如@Binary Worrier在评论中指出的那样,这对STL容器不起作用,因为它们有 2 模板参数:一个用于元素类型,另一个用于类型用于管理存储分配的分配器(具有默认值)。
因此,您需要更改第一个模板参数,使其具有两个参数:
template <template <typename,typename> class CollectionType, class ItemType>
class Test
{
public:
CollectionType<ItemType> m_collection;
};
但等等,这也行不通!实际上,CollectionType
等待另一个参数,分配器......所以现在你有两个解决方案:
1。强制使用特定的分配器:
CollectionType<ItemType, std::allocator<ItemType> > m_collection
2。将分配器的模板参数添加到您的类:
template <template <typename,typename> class CollectionType,
class ItemType,
class Allocator = std::allocator<ItemType> >
class Test
{
public:
CollectionType<ItemType, Allocator> m_collection;
};
正如你所看到的,你最终会得到一些相当复杂的东西,这似乎对处理STL容器感到非常麻烦......
我的建议:请参阅格雷格罗杰斯对更好方法的回答:)!
答案 1 :(得分:10)
为什么不这样做?
template <class CollectionType>
class Test
{
public:
CollectionType m_collection;
};
Test t = Test<vector<int> >();
t.m_collection = vector<int>();
如果您需要itemtype,可以使用CollectionType::value_type
。
编辑:在回答有关创建返回value_type的成员函数的问题时,您可以这样做:
typename CollectionType::value_type foo();
您添加了typename,因为CollectionType尚未绑定到实际类型。所以它没有可以查找的value_type。
答案 2 :(得分:2)
Comeau online喜欢这个:
#include <vector>
template <template <class T, class A = std::allocator<T> > class CollectionType, class ItemType>
class Test
{
public:
CollectionType<ItemType> m_collection;
};
void foo()
{
using std::vector;
Test<vector,int> t = Test<vector, int>();
t.m_collection = vector<int>();
}