模板模板参数方案
template template parameter scenario
我有一个模板类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和其他版本兼容(可以模拟任何其他版本,如果你向他们传递一个向量,列表或你的异国情调的容器。只要它们符合您的类期望的接口。
相关文章:
- 如何反转整数参数包
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 模板模板参数方案
- 带有"up-"和"center-vec3"参数的glm::rotate()的有效替代方案?
- 继承是否是将一组模型参数传递给不同类的可行解决方案
- 用于在 Visual Studio 中为整个项目或解决方案定义带有参数的预处理器宏的选项
- 在 C++14 中,是否有一种优雅的解决方案可以在可变参数模板中选择可调用和不可调用的类型
- 从Swift中的通用参数继承的替代方案
- 如何在Xcode 5中使用编辑方案将参数传递给main.cpp
- 使用模板模板参数的替代方案
- 任何解压缩向量以在C++中函数参数的解决方案
- 单例方案,使用不同的参数重载 getInstance
- 具有递归可变参数模板的函数的部分模板专用化的替代方案
- 用于未使用参数参考的单线解决方案
- 采用N个参数并返回N个值的高性能解决方案
- 使用强typedef作为Boost参数库的更轻量级的替代方案
- std::enable_if和模板模板参数显式重载的替代方案
- 将include/library目录和链接器参数传播到解决方案中的所有项目
- OpenGL GLEW的替代品,定义了参数或解决方案
- 函数参数 -> 结构体成员的 void* 和常量 void* 的解决方案