在Stroustrup的书(第4版 - 第一次打印)的第668页中,您将找到以下模板类示例?
template<typename C>
class String{
public:
String();
...
private:
int sz;
C* ptr;
};
Run Code Online (Sandbox Code Playgroud)
在第679页中,作者写道:
模板类的成员本身是由其模板类的参数参数化的模板.当这样的成员在其类之外定义时,它必须明确声明为模板.例如:
Run Code Online (Sandbox Code Playgroud)template<typename C> String<C>::String() :sz(0), ptr(ch) { ch[0] = {}; }
这个例子中有一个明显的错误.变量ch 在上面没有任何意义.但这与我的问题无关.我想知道的是为什么没有参数就无法定义上面的构造函数C,如下所示?
template<typename C>
String::String()
: sz(0), ptr(nullptr)
{
}
Run Code Online (Sandbox Code Playgroud)
String是模板的名称,而不是类.模板甚至不是一个类型,因此它没有成员.但是,模板专门化是一个类.您需要插入C以指定出于此定义的目的而指定的特殊化.
现在恰好是定义本身就是一个模板,但这是因为你为一系列专业化定义了东西.然而,事实仍然是您需要明确地命名这些特化.
最后,您只需要指定一次特化的原因是模板名称在类模板特化的范围内以特殊方式处理.在该范围内,模板名称指的是注入的类名称,指向特化本身.这就是为什么
template<typename C>
String<C>::String<C>()
:sz(0), ptr(ch)
{
}
Run Code Online (Sandbox Code Playgroud)
......可写成......
template<typename C>
String<C>::String()
:sz(0), ptr(ch)
{
}
Run Code Online (Sandbox Code Playgroud)
既然String<C>已经建立了我们所指的专业化,并且我们在其范围内,我们可以使用String其特殊含义作为注入类名.