c++学习(函数模板, 类模板)<2>
2015-11-23 13:58
537 查看
ps: 不知道为什么<1> 的后面显示不全 。。。 即使删一点前面的文字也显示不全。。。。,等有机会了一定自己搭博客
而如果加上const:int big(const T &a,const T &b)那么就可以: cout<
在类A中声明了两个类型为T的成员变量a和b,还声明了一个返回类型为T带两个参数类型为T的函数hy。
注意:
起始要注意的地方跟普通函数差别不是很大
1.如果在全局域中声明了与模板参数同名的变量,则该变量被隐藏掉。
2.模板参数名不能被当作类模板定义中类成员的名字。
3.同一个模板参数名在模板参数表中只能出现一次。
4.在不同的类模板或声明中,模板参数名可以被重复使用。
5.对于函数模板而言不存在 h(int,int) 这样的调用,不能在函数调用的参数中指定模板形参的类型,对函数模板的调用应使用实参推演来进行,即只能进行 h(2,3) 这样的调用,或者int a, b; h(a,b)。
6.类模板形参不存在实参推演问题。就是 template<2>是error
7. 类模板会完成自动类型转换
8. 模板可以作为参数http://www.cnblogs.com/zhengyuhong/archive/2013/11/04/3406699.html
类模板中的非形参类型
1.非类型形参在模板定义的内部是常量值,也就是说非类型形参在模板的内部是常量。
2.非类型模板的形参只能是整型,指针和引用,像double,String, String *这样的类型是不允许的。但是double &,double ,对象的引用或指针是正确的。
3.调用非类型模板形参的实参必须是一个常量表达式,即他必须能在编译时计算出结果。
4。注意:任何局部对象,局部变量,局部对象的地址,局部变量的地址都不是一个常量表达式,都不能用作非类型模板形参的实参.全局变量的地址或引用,全局对象的地址或引用const类型变量是常量表达式,可以用作非类型模板形参的实参。sizeof表达式的结果是一个常量表达式,也能用作非类型模板形参的实参。
类模板的实例化
显式具体化,隐式实例化,部分具体化
1.隐式实例化(implicit instantiation)比较简单,它是在函数调用时根据参数的具体类型来确定函数模板中的泛型类型。
2.显式具体化:是特定类型的定义.当通用类型不起作用的时候,我们可以提供一个显式具体化,这将采用为具体类型定义的模板,而不是为通用类型定义的模板
具体化类模板格式
double 部门就是对 A的显示具体化
3.部分具体化: 部分限制通用性
类模板的友元声明
模板的友元分三类
参考 :http://www.cnblogs.com/li-peng/p/3512887.html
- 非模板友元
- 约束(bound)模板友元(友元的类型取决于类被实例化时的类型)
- 非约束(unbound)模板友元(友元的所有具体化都是类的每一个具体化友元)
约束友元函数
参考:http://www.cnblogs.com/assemble8086/archive/2011/10/02/2198308.html
而如果加上const:int big(const T &a,const T &b)那么就可以: cout<
template<class type,int width> //type为类型参数,width为非类型参数
在类A中声明了两个类型为T的成员变量a和b,还声明了一个返回类型为T带两个参数类型为T的函数hy。
注意:
起始要注意的地方跟普通函数差别不是很大
1.如果在全局域中声明了与模板参数同名的变量,则该变量被隐藏掉。
2.模板参数名不能被当作类模板定义中类成员的名字。
3.同一个模板参数名在模板参数表中只能出现一次。
4.在不同的类模板或声明中,模板参数名可以被重复使用。
5.对于函数模板而言不存在 h(int,int) 这样的调用,不能在函数调用的参数中指定模板形参的类型,对函数模板的调用应使用实参推演来进行,即只能进行 h(2,3) 这样的调用,或者int a, b; h(a,b)。
6.类模板形参不存在实参推演问题。就是 template<2>是error
7. 类模板会完成自动类型转换
8. 模板可以作为参数http://www.cnblogs.com/zhengyuhong/archive/2013/11/04/3406699.html
#include <iostream> #include <stdio.h> #include <algorithm> #include <sstream> #include <string.h> using namespace std; template<class T> class A{ public: T g(T a,T b); A(); }; template<class T> A<T>::A(){} template<class T> T A<T>::g(T a,T b){ return a+b; } int main(){ A<int> a; cout<<a.g(2,3.2)<<endl; return 0; }
类模板中的非形参类型
1.非类型形参在模板定义的内部是常量值,也就是说非类型形参在模板的内部是常量。
2.非类型模板的形参只能是整型,指针和引用,像double,String, String *这样的类型是不允许的。但是double &,double ,对象的引用或指针是正确的。
3.调用非类型模板形参的实参必须是一个常量表达式,即他必须能在编译时计算出结果。
4。注意:任何局部对象,局部变量,局部对象的地址,局部变量的地址都不是一个常量表达式,都不能用作非类型模板形参的实参.全局变量的地址或引用,全局对象的地址或引用const类型变量是常量表达式,可以用作非类型模板形参的实参。sizeof表达式的结果是一个常量表达式,也能用作非类型模板形参的实参。
类模板的实例化
显式具体化,隐式实例化,部分具体化
1.隐式实例化(implicit instantiation)比较简单,它是在函数调用时根据参数的具体类型来确定函数模板中的泛型类型。
template<class T> class A{public: T a; T b; T hy(T c, T &d);}; int a, b; a<int> a;
2.显式具体化:是特定类型的定义.当通用类型不起作用的时候,我们可以提供一个显式具体化,这将采用为具体类型定义的模板,而不是为通用类型定义的模板
具体化类模板格式
Template <> class Classname<specialized-type-name>{}; #include <iostream> #include <stdio.h> #include <algorithm> #include <sstream> #include <string.h> using namespace std; double aa = 1.0; template<class T> class A{ public: T g(T a,T b); A(); }; template<class T> A<T>::A(){} template<class T> T A<T>::g(T a,T b){ return a+b; }; template <> class A <double >{ public: double g(double a,double b){ cout<<"Double"<<endl; return a+b; }; A(){}; }; int main(){ A<int> b; cout<<b.g(1, 'a')<<endl; A<double> a; cout<<a.g(2.0,'a')<<endl; return 0; }
double 部门就是对 A的显示具体化
3.部分具体化: 部分限制通用性
#include <iostream> #include <stdio.h> #include <algorithm> #include <sstream> #include <string.h> using namespace std; //general template template<class T1, class T2> class A{ public: T1 g(T1 a,T2 b); A(); }; template<class T1, class T2> A<T1, T2>::A(){} template<class T1, class T2> T1 A<T1, T2 >::g(T1 a,T2 b){ return a+b; }; // specialization with T2 set to int // 部分具体化 template<class T1> class A<T1, int> { public: T1 g(T1 a,int b){ cout<<"special"<<endl; return a; }; A(){}; }; // specialized definition template <> class A <double , double>{ public: double g(double a,double b){ cout<<"Double"<<endl; return a+b; }; A(){}; }; int main(){ A<double, double > c; cout<<c.g(2, 1)<<endl; A<int, int> b; cout<<b.g(1, 1)<<endl; A<double, int> a; cout<<a.g(2.0, 1)<<endl; return 0; }
类模板的友元声明
模板的友元分三类
参考 :http://www.cnblogs.com/li-peng/p/3512887.html
- 非模板友元
- 约束(bound)模板友元(友元的类型取决于类被实例化时的类型)
- 非约束(unbound)模板友元(友元的所有具体化都是类的每一个具体化友元)
template <class T> class HasFriend{ // friend void report(HasFriend &){}; error , 没有具体化 riend void report(HasFriend<T> &){};bound template friend;
约束友元函数
template<class type> void create(Graphics<type>); template<class type> class Graphics{ friend void create<type>(Graphics<type>); };
参考:http://www.cnblogs.com/assemble8086/archive/2011/10/02/2198308.html
相关文章推荐
- c语言如何获取时间
- c++数据类型间的转换
- 2034-人见人爱A-B(c++实现)
- C语言学习——终于认清了的for循环
- C语言基础第二篇--基本数据类型
- volatile的用处
- c和c++中的一维数组和二维数组的动态分配内存,以及参数传递
- C语言基础第一篇--Hello world !
- C++中两个类相互包含引用问题
- C语言函数指针
- 判断从出生到18岁生日一共度过了多少天
- C语言中mktime函数功能及用法
- C++内存使用机制基本概念详解
- C++如何在r3静态调用NT函数
- C语言多继承时子类与基类指针关系,union与struct区别,volatile修饰符作用
- C++ enum用法
- C++ STL源码剖析
- C语言运算符优先级 详细列表
- C++ enum用法
- STL memory.cpp