模板模板参数方案

template template parameter scenario

本文关键字:方案 参数      更新时间:2023-10-16

我有一个模板类MYVEC它作为第二个模板参数传递给另一个模板类FOO

template<class T>
class MYVEC{ };
template<class T,class U>
class FOO { };
main()
{
FOO<int, MYVEC<int>> obj;
}

如果我可以用上述方式实例化FOO,那么为什么我需要模板模板参数语法?

例如,我什么时候需要以下内容:

template<class T>
class MYVEC{ };
template<class T, template<typename> class C>  //or     template<class T, template<typename> class C=MYVEC>
class FOO { };

此外,我的编译器在尝试将其实例化为:

FOO<int, MYVEC> obj; //I wonder what is the second template param type  here

但这是一个编译器错误,尽管我希望这可以工作:

FOO<int, MYVEC<int>> obj;

切入错误的严重性,它本质上是在告诉您MYVEC<int>不是模板类型,因为该类型已完全实现。而当您使用MYVEC时,这是一种模板类型,因为它仍然需要一个模板参数。

如果我可以用上述方式实例化FOO,那么为什么我需要模板模板参数语法呢?

因为您可以防止FOO以有问题的方式实例化,例如

main()
{
FOO<int, MYVEC<std::string>> obj2; // Probably fails to compile with a cryptic message
FOO<int, MYVEC<short>> obj3; // Hopefully fails to compile, could easily have undefined behaviour
}

模板模板参数有一个适用的利基区域。

假设您有一个管理某个资源的类。现在,您可以将它们存储在矢量中,或者将列表或您制作的一些异国情调的容器中存储。或者,您可以通过模板模板参数作为类定义的一部分请求容器类型,从而完全将选择留给用户。

一些代码来说明差异。

template<typename T> class MyResManagerv1
{
std::vector<T> resources;
// rest of your implementation details
// rest of your public interface
};
MyResManagerv1<my_file_type> v1;
template<typename T> class MyResManagerv2
{
std::list<T> resources;
// rest of your implementation details
// rest of your public interface
};
MyResManagerv2<my_file_type> v2;
template<typename T> class MyResManagerv3
{
my_exotic_container<T> resources;
// rest of your implementation details
// rest of your public interface
};
MyResManagerv3<my_file_type> v3;
template<typename T, template<typename> class container> class MyResManagerv4
{
container<T> resources;
// rest of your implementation details
// rest of your public interface
};
MyResManagerv4<my_file_type, std::vector> v4;
MyResManagerv4<my_file_type, std::list> v5;
MyResManagerv4<my_file_type, my_exotic_container> v6;

这个最终版本(仅C++17,可以调整为与C++11和其他版本兼容(可以模拟任何其他版本,如果你向他们传递一个向量,列表或你的异国情调的容器。只要它们符合您的类期望的接口。