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