http://bbs.csdn.net/topics/391819297?page=1#post-401187341
偶然看到这个帖子,对于其中的模版模版参数的写法有点疑惑,本人试了一下,
在VS2008 (VC9.0)中正确的写法如下。
偶然看到这个帖子,对于其中的模版模版参数的写法有点疑惑,本人试了一下,
在VS2008 (VC9.0)中正确的写法如下。
namespace std { // 示例类模版1 template <typename _Ty1, typename _Ty2> struct Test1 { Test1() : data(0) {} ~Test1() {} DWORD data; }; // 示例类模版2 template <typename _Ty1, typename _Ty2> struct Test2 { Test2() : data(0) {} ~Test2() {} DWORD data; }; // 全局链表,用于缓存 list<Test1<DWORD, DWORD>> g_list_test1; list<Test2<DWORD, DWORD>> g_list_test2; // 用于创建一个新实例的方法,原本目的是用于标准库容器类 // 隐含的条件:类模版的不同的特化模版类的大小与模版参数无关 // (几个基本的标准库容器均符合此条件,除了vector<bool>对应于 // 一个偏特化的子类模版,需要特别注意一下) void* _func(DWORD nType) { switch (nType) { case 1: { g_list_test1.push_back(Test1<DWORD, DWORD>()); return &g_list_test1.back(); } case 2: { g_list_test2.push_back(Test2<DWORD, DWORD>()); return &g_list_test2.back(); } default: ASSERTF(); break; } return NULL; } // 因函数模版不支持偏特化,所以需要先声明类模版, // 实现对DWORD nType的编译期动态 template <template<typename _Ty1, typename _Ty2> class _Container> struct _ContainerType; template <> struct _ContainerType<Test1> { enum { type=1 }; }; template <> struct _ContainerType<Test2> { enum { type=2 }; }; // 外包的模版函数 template <typename _Ty1, typename _Ty2, template<typename _Ty1, typename _Ty2> class _Container> _Container<_Ty1, _Ty2>& func() { return *(_Container<_Ty1, _Ty2>*)_func(_ContainerType<_Container>::type); } }
要点在代码注释中都写出来了。
解释下,模版模版参数或说模版参数是类模版类型,是对类模版实现编译期动态,
其特化形式是类模版而不是特化的模版类。但是类模版是不能实例化的,而我们又
需要实例化,所以需要将类模版的模版参数显式指定,也即做为外层模版的模版参数,
调用时显式传入。
解决方案
5
能解释下常量模板的概念么?第一次听说
20
说的完全不是一件事啊
首先明确一点
首先明确一点
template <typename _Ty1, typename _Ty2, template<typename _Ty1, typename _Ty2> class _Container> _Container<typename, typename>& func();
这样的写法是语法错误,只不过 msvc 照 C 语言传统将没有出现的依赖名称默认为 int 了,才推导出返回类型为 _Container<int, int>
可以省略的是模板参数名——假如你不使用的话——像这样:
template <typename _Ty1, typename _Ty2, template<typename, typename> class _Container> _Container<_Ty1, _Ty2>& func()
这里的 template class _Container 只是个声明,因此其参数名可以省略,就像前置模板声明
template <typename> class X;
或前置函数声明
void func(int, double);
参数名皆可省略
5
谢谢,学习了
。
。
10
switch要加break