本文内容出自中文版《C++标准程序库》,特此声明。
之前看了《C++标准程序库》中的第二章简介中的成员模板,似乎一直一知半解。今天重看,突然豁然开朗。
把书中的两个例子摘抄于此。相信自有受益者。觉得经典书籍毕竟是经典,比很多书中讲的好。
Member Template
Class member funcion可以是个Template,但则有的member template既不能是VIRTUAL,也不能有缺省参数。
例如:
class MyClass
{
…
template
void f(T);
};
在这里,MyClass::f声明了一个成员函数集,适用任何型别参数。只要某个型别提供有f()所用到的所有操作,它就可以被当作参数传递进去。
这个特性通常用来为template classes中的成员提供自动类型转换。(我认为这个特性是指:MEMBER TEMPLATE)
例如以下定义中,assign()的参数X,其类型必须和调用端提供的对象的类型完全吻合:(为T)
template
class MyClass
{
private:
T value;
public:
void assign(const MyClass& x)
{
value = x.value;
}
};
按照上面定义,即使两个型别之间可以自动转换,如果我们对assign()使用不同的template型别,也会出错。
void f()
{
MyClass d;
MyClass i;
d.assign(d); // OK
d.assign(i);// error
}
如果不是模板的话,int是可以向double转换的,但是模板是匹配的整体。
如果C++允许我们为member function提供不同的template型别,就可以放宽“必须精确吻合”的这条规则:只要型别可以赋值,就可以被当作上述member template funtion的参数:
template
class MyClass
{
private:
T value;
public:
template // member template
void assign(const MyClass& x)
{
value = x.getvalue();
}
T getvalue() const
{
return value;
}
};
void f()
{
MyClass d;
MyClass i;
d.assign(d); // OK
d.assign(i); // OK
}
请注意,现在assign()的参数X和*this的型别并不相同,所以你不再能够直接存取MyClass<>的private和protected成员,取而代之的是,此例中你必须使用类似getvalue()之类的函数。
Template constructor是member template的一种特殊形式。Template constructor 通常用于“在复制对象时实现隐式类别转换”。请注意,template constructor并不遮盖implicit constructor。如果型别完全吻合,implicit copy constructor就会被产生并调用。
举个例子:
template
class MyClass
{
public:
template
MyClass (const MyClass
& x);
…
};
void f()
{
MyClass xd;
…
MyClass xd2(xd); // implicit copy constructor
MyClass xi(xd); // template constructor
}
记得之前同事看过的代码里面就有member template的使用。