鉴于以下课程
template <class T>
class A {
static const B<T> member;
};
Run Code Online (Sandbox Code Playgroud)
如何单独member为每个类实例化A<T>?
简单.和其他任何静态非整数类型一样.
template <class T>
class A {
static const B<T> member;
};
template <class T>
const B<T> A<T>::member/*(optional-args)*/;
Run Code Online (Sandbox Code Playgroud)
要为不同类型的成员分配不同的成员T,必须使用模板专门化.
要启动模板特化,您必须使用以下语法:
template<>
// ... explicit definition
Run Code Online (Sandbox Code Playgroud)
显式定义的语法基本上与以下语法相同:
template <class T>
const B<T> A<T>::member/*(optional-args)*/;
Run Code Online (Sandbox Code Playgroud)
除了,template <class T>您使用,而不是在template<>哪里T,您放置实际类型.
例如:
template<>
const B<type> A<type>::member(args);
Run Code Online (Sandbox Code Playgroud)
注意:如果您希望在此方案中调用具有模板特化的默认构造函数,请参阅下面的编辑.
您可以替换type任何您想要的类型.有了这个,您可以为每种可能的类型提供不同的参数.虽然如果你太专注,你应该考虑你的设计是否真的适合使用模板.
在这里它是在行动(在线),随意克隆和玩它.
我想我会提到声明必须是模板类所在的位置.换句话说,如果A在标头中声明,则还必须member在头文件中声明分配.您也可以使用内联文件(.inl)和#include声明模板类的头文件中的.inl文件.
似乎在C++ 98中,如果引用成员变量,则调用默认构造函数的以下语法不会在GCC或clang下编译:
template <>
const B<type> A<type>::member/*()*/;
Run Code Online (Sandbox Code Playgroud)
类型是任何类型.
但是,以下情况:
template <class T>
const B<T> A<T>::member/*()*/;
Run Code Online (Sandbox Code Playgroud)
我不确定这是一个错误,还是只是错误的语法.我建议改为做以下事项:
template <>
const B<type> A<type>::member = B<type>();
Run Code Online (Sandbox Code Playgroud)
或者如果您使用的是C++ 11,则可以使用大括号来调用默认构造函数,如下所示:
template <>
const B<type> A<type>::member{};
Run Code Online (Sandbox Code Playgroud)
如果使用常规括号,编译器将会在A<type>类中使用静态函数,如果不使用括号,则会出现undefined reference to 'A<type>::member'链接器错误.您可以在这里看到.
以下是Aaron和我发现此错误的讨论.