1.模板
//模板里面也可以有非类型的参数,原则上只能是整数,而且是字面量
字面量在编译时就确定下来。
也可以有默认值
template<typename T,int size=10>
stack<char,20>s;
一般的类型使用模板就可以搞定,特殊的类型就使用特化
想查看实际替换时是什么类型,这就需要运行时类型识别函数了typeid
最好不要把模板的声明与定义分开,麻烦
模板的特化:
例子:
template<int n>
class Fact
{
public:
enum{val=Fact<n-1>::val*n};
};
template <>
class Fact<0>
{
public:
enum{val=1};
};
template <typename T>
class Type
{
public:
static string name(){reurn typeid(T).name(); }
};
class Type<char>
{
public:
static const char* const name;
};
const char* const Type<char>::name="char";
template <typename T>
class Type<T*>
{
public:
static string name(){reurn Type<T>)::name()+"pointer"; }
};
int main()
{
cout<<Fact<5>::val<<endl;
cout<<Type<double>::name()<<endl;
cout<<Type<char>::name()<<endl;
cout<<Type<int*>::name()<<endl;
}
类模板
如果成员函数中有类型参数存在,则需要在成员函数定义之前进行模板声明,并且
在成员函数名前加上 类名<类型参数>::
模板类可以有多个类型参数
例子:
template<typename T1,typename T2> //声明具有两个类型参数的模板
class compare
{
public:
compare(T1 a,T2 b);
void show()
{
cout<<"a="<<a<<endl<<"b="<<b<<endl;
}
private:
T1 a;
T2 b;
};
template<typename T1,typename T2> //在成员函数定义之前进行模板声明
compare<T1,T2>::compare(T1 a,T2 b):a(a),b(b)
{ }
int main()
{
compare<int,const char*>ob1(1,"this is a test.");
ob1.show();
return 0;
}
例子:带两个参数的类模板
template <typename To, typename From>
To convertto(From v)
{
return To(v);
}
template <typename To>
To convertto(const char* str)
{
return To(atof(str));
}
template <typename T, typename U>
struct Pair
{
T first;
U second;
Pair():first(),second(){}
Pair(const T& a, const U& b):first(a),second(b){}
template<typename X, typename Y>
Pair& operator=(const Pair<X,Y>& p){
first = convertto<T>(p.first);
second = convertto<U>(p.second);
return *this;
}
};
template <typename T, typename U>
ostream&operator<<(ostream& o, const Pair<T,U>& p)
{
return o<<p.first<<':'<<p.second;
}
template <typename T, typename U>
Pair<T,U> mp(T f, U s) //返回一个模板
{
return Pair<T,U> (f,s);
}
int main()
{
cout << Pair<const char*,int>("芙蓉",18) << endl;
cout << Pair<int,double>(20,6789.5) << endl;
cout << mp("芙蓉",18) << endl;
cout << mp(20,6789.5) << endl;
Pair<int,double> a(123,45.6);
cout << "a=" << a << endl;
Pair<const char*,const char*> b("78","90.5");
a = b;
cout << "a=" << a << endl;
//模板里面也可以有非类型的参数,原则上只能是整数,而且是字面量
字面量在编译时就确定下来。
也可以有默认值
template<typename T,int size=10>
stack<char,20>s;
一般的类型使用模板就可以搞定,特殊的类型就使用特化
想查看实际替换时是什么类型,这就需要运行时类型识别函数了typeid
最好不要把模板的声明与定义分开,麻烦
模板的特化:
例子:
template<int n>
class Fact
{
public:
enum{val=Fact<n-1>::val*n};
};
template <>
class Fact<0>
{
public:
enum{val=1};
};
template <typename T>
class Type
{
public:
static string name(){reurn typeid(T).name(); }
};
class Type<char>
{
public:
static const char* const name;
};
const char* const Type<char>::name="char";
template <typename T>
class Type<T*>
{
public:
static string name(){reurn Type<T>)::name()+"pointer"; }
};
int main()
{
cout<<Fact<5>::val<<endl;
cout<<Type<double>::name()<<endl;
cout<<Type<char>::name()<<endl;
cout<<Type<int*>::name()<<endl;
}
类模板
如果成员函数中有类型参数存在,则需要在成员函数定义之前进行模板声明,并且
在成员函数名前加上 类名<类型参数>::
模板类可以有多个类型参数
例子:
template<typename T1,typename T2> //声明具有两个类型参数的模板
class compare
{
public:
compare(T1 a,T2 b);
void show()
{
cout<<"a="<<a<<endl<<"b="<<b<<endl;
}
private:
T1 a;
T2 b;
};
template<typename T1,typename T2> //在成员函数定义之前进行模板声明
compare<T1,T2>::compare(T1 a,T2 b):a(a),b(b)
{ }
int main()
{
compare<int,const char*>ob1(1,"this is a test.");
ob1.show();
return 0;
}
例子:带两个参数的类模板
template <typename To, typename From>
To convertto(From v)
{
return To(v);
}
template <typename To>
To convertto(const char* str)
{
return To(atof(str));
}
template <typename T, typename U>
struct Pair
{
T first;
U second;
Pair():first(),second(){}
Pair(const T& a, const U& b):first(a),second(b){}
template<typename X, typename Y>
Pair& operator=(const Pair<X,Y>& p){
first = convertto<T>(p.first);
second = convertto<U>(p.second);
return *this;
}
};
template <typename T, typename U>
ostream&operator<<(ostream& o, const Pair<T,U>& p)
{
return o<<p.first<<':'<<p.second;
}
template <typename T, typename U>
Pair<T,U> mp(T f, U s) //返回一个模板
{
return Pair<T,U> (f,s);
}
int main()
{
cout << Pair<const char*,int>("芙蓉",18) << endl;
cout << Pair<int,double>(20,6789.5) << endl;
cout << mp("芙蓉",18) << endl;
cout << mp(20,6789.5) << endl;
Pair<int,double> a(123,45.6);
cout << "a=" << a << endl;
Pair<const char*,const char*> b("78","90.5");
a = b;
cout << "a=" << a << endl;
}