一个以模板函数完成的输出(<<)运算符
非模板函数形式的重载运算符函数是这样(声明)
ostream& operator<<(ostream&,const BinaryTree<int>&);
而模板函数形式的重载运算符函数是这样(定义)
template <typename elemType>
inline ostream&
operator<<(ostream &os,const BinaryTree<elemType>&bt)
{
os<<"Tree:"<<endl;
bt.print(os);
return os;
}
int main()
{
BinaryTree<string>bts;
cout<<bts<<endl;
//编译器将elemType指定为string,产生一个对应的(针对BinaryTree<string>类型的)<<运算符。
BinaryTree<int>bti;
cout<<bti<<endl;
//编译器将elemType指定为int,产生一个对应的(针对BinaryTree<int>类型的)<<运算符
}
- 总的来说,就是模板类要适配一个模板函数,以免重载运算符函数用于模板类上则需要定义很多很多不同的第二参数的类型的这样的重载运算符函数
常量表达式与默认参数值
- 可以用常量表达式作为模板参数,而且以常量表达式作为模板参数(<>内的参数)还可以给这个模板参数提供默认值,举个例子
如:
template<int len,int beg_pos>
class num_sequence{//还记得这是个基类吗,其派生类是Fibonacci
public:
virtual ~num_sequence(){};
int elem(int pos)const;
const char* what_am_i()const;
static int max_elems(){return _max_elems;}
ostream& print(ostream &os=cout) const;
protected:
virtual void gen_elems(int pos) const = 0;
bool check_integrity(int pos,int size)const;
num_sequence(vector<int>*pe):_pelems(pe){}//定义基类类构造函数
static const int _max_elems=1024;
vector<int> *_pelems;
};
template<int len,int beg_pos>ostream&
//<<运算符的模板函数定义,注意第二参数的写法,因为模板类带了两个常量表达式作为了模板参数(<>内的参数),
//所以这个第二参数也要写成带两个常量表达式作为模板参数(<>内的参数)的形式
operator<<(osteram&os,const num_sequence<len,beg_pos>&ns)
{
return ns.print(os);
}
模板参数默认值
还有带默认模板参数值的模板类定义写法:
template<int length,int beg_pos=1>//这里模板参数(<>内的参数)为常量表达式(或者说普通变量),
//然后有的模板参数(<>内的参数)给了默认参数值(你可以选择替换这个默认参数值,不替换就默认)
class Fibonacci:public num_seuqence<length,beg_pos>{
public:
Fibonacci():num_sequence<length,beg_pos>(&_elems){}
protected:
virtual void gen_elems(int pos)const;
static vector<int> _elems;
};
全局作用域内的函数及对象用于模板类
全局作用域内的函数和对象的地址是常量表达式(或说是常数),可以用来做模板参数。举个例子:以函数指针作为参数的数列类
template<void (*pf)(int pos,vector<int>&seq)>//函数指针作为模板参数!(<>内的参数)
class numeric_sequence
{
public:
numeric_sequence(int len,int beg_pos=1)//类构造函数定义
{
if(!pf)//检查函数指针指向是否为null
{
//....产生错误信息并退出该构造函数
}
//。。。
private:
int _len;
int _beg_pos;
vector<int> _elems;
};
该作为模板类的模板参数(<>内的参数)函数指针用法如下:
//pf函数指针指向一句特定数列类型,产生pos个元素,放到vector容器seq内的函数
void fibonacci(int pos,vector<int>&seq);
void pell(int pos,vector<int>&seq);
//...
numeric_seuqence<fibonacci> ns_fib(12);//fibonacci函数地址赋给了pf
numeric_seuqnece<pell> ns_peel(18,8);//pell函数地址赋给了pf