我对模板模板参数有疑问:
让我们考虑以下课程:
template<typename T, template<class, class=std::allocator<T> > class UnderlyingContainerType = std::vector>
class MyContainer
{
public:
T Value1;
T Value2;
UnderlyingContainerType<T> Container;
MyContainer() {}
/* methods implementation goes here */
};
在这个例子中,MyContainer是一个容器聊天使用底层的STL兼容容器来做任何事情。
将基础容器类型声明为模板模板参数,而不是常规模板参数,允许方便地使用类MyContainer,例如:
MyContainer<int> MCV; //implicitly using vector
MyContainer<int, std::list> MCL; //no need to write std::list<int> thanks to the
//template template parameters
现在,虽然这可以与大多数STL容器完美配合,例如std :: vector,std :: deque,std :: list等等,但它不起作用,例如,使用std: :在c ++ 11中提供的数组。
原因是std :: array具有与vector不同的模板参数签名。具体来说,它们是:
std::vector<class T, class allocator = std::allocator<T> >
std::array<class T, int N>
我的问题是,是否有一种方法可以概括MyContainer类,以便底层容器也可以是std :: array。
我提前感谢你。
答案 0 :(得分:3)
vector
和array
的接口之间的通用性仅限于元素类型。您的容器应该反映出:
template<typename T, template<typename> class underlying_container>
struct container
{
underlying_container<T> storage;
};
现在使用需要一个小技巧:
template<typename T> using vec = vector<T>;
template<typename T> using arr2 = array<T, 2>;
请注意,与vec
不同,vector
具有固定的分配器,与arr2
不同,array
具有固定的大小。
现在用法很简单:
container<int, vec> a;
container<double, arr2> b;
或者,如果您希望将接口与vector使用的接口匹配,只需为array
添加实例化大小的模板别名,并添加未使用的类型参数:
template<typename T, typename> using arr2 = array<T, 2>;
答案 1 :(得分:2)
我不知道如何准确地实现,你想要什么。但如果您不需要能够编写MyContainer<int> MCV;
,则可以使用
template<class UnderlyingContainerType, class T = typename UnderlyingContainerType::value_type>
class MyContainer
{
public:
T Value1;
T Value2;
UnderlyingContainerType Container;
MyContainer() {}
/* methods implementation goes here */
};
int main() {
MyContainer<std::vector<int>> MCV{};
MyContainer<std::array<int, 5>> MCA{};
}
键入的内容不仅仅是MyContainer<int, std::vector> MCV;
当然,您仍然可以为基于矢量的版本添加别名:
template<class T>
using MyContainerV = MyContainer < std::vector<T> > ;