64,688
社区成员
发帖
与我相关
我的任务
分享
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);
}
}
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);
参数名皆可省略
template <template<typename _Ty1, typename _Ty2> class _Container>
_Container<typename, typename>& func();
所以在如底楼的函数模版定义里,建议还是不要省略,以免出问题。