首页
登录 | 注册

STL标准模板库

函数模板的定义与使用

函数家族、语法形式、类型参数、typename、实例化、二次编译、包含模型。

函数模板包含两种参数,一种是模板参数,即在模板名之前,用一对尖括号括起来的参数;

另一种是调用参数,在模板名之前,用一对圆括号括起来的参数

如果函数模板调用参数的类型相关于该模板时,即使不显式指定模板参数,编译器也有能力根据参数的类型隐式推断出正确的模板参数,来获得与普通函数调用相同的语法表达。

#include<cstdlib>

#include<iostream>

#include<typeinfo>

Using namespace std;

 

template<typename T>

void fun1(T cinst& x, T const& y){

    cout <<typeid(x).name()<<’’<<typeid(y).name()<<endl;

}

template<typename T>

void fun2(T x,T y){

    cout <<typeid(x).name()<<’’<<typeid(y).name()<<endl;

}

template<typename R,typename T>

R fun3(T const& t){

    R r;

cout<<typeid(t).name()<<’’<<typeid(r).name()<<endl;

return r;

}

Int main(){

    Int a,b;

    Fun1(a,b); //输出的是int类型的引用 i i

    Float c,d;

Fun2(c,d);//输出的是float类型的引用 f f

   

    return 0;

}

g++ 编译链接

a.out运行输出

 

void fun1(T cinst& x, T const& y)  常引用有什么好处呢?如果实际传递的函数实参是个复杂对象,那么就可以避免对象之间的拷贝,即减少了函数调用的开销,又避免了深浅拷贝带来的麻烦。

 

模板与类:

从类模板到实际上经历了两个实例化过程:

编译期:编译器将类模板实例化为类并生成对象创建指令

运行期:处理器执行对象创建指令将类实例化为内存对象。

类模板本身不代表一个类型,只有通过模板实参将其实例化为具体类以后,才具备通常所说的类型语义,可被用于对象的声明和定义

类模板名<类型实参1,类型实参2,…>

Ex:

Stack<int>si;

Stack<int>* ps=&si;

Stack<int>& rs=si;

在类模板的定义中,一般采用 类模板名<模板参数>的形式,但多数编译器也允许将其简化为“类模板名”

template<typename T>

class Stack{

    public:

    Stack(Stack <T> const& that){…}

    Stack<T>&operator= (Stack<T> const& rhs) {…}

};

 

 

 

使用typeid(变量或类型).name()来获取常量或变量的类型

<typeinfo>  该头文件包含运行时类型识别(在执行时确定数据类型)的类

typeid的使用

 

typeid操作符        typeid表达式形如:      typeid(expr);

这里expr是任意表达式或者类型名。如果表达式的类型是类类型且至少包含有一个虚函数,则typeid操作符返回表达式的动态类型,需要在运行时计算;否则,typeid操作符返回表达式的静态类型,在编译时就可以计算。

typeid操作符的返回结果是名为type_info的标准库类型的对象的引用(在头文件typeinfo中定义),因此使用typeid操作符时要包含头文件typeinfo的预处理命令“#include <typeinfo>”。标准并没有确切定义type_info,它的确切定义编译器相关的,但是标准却规定了其实现必需提供如下四种操作:

 

 t1 == t2    

 如果两个对象t1和t2类型相同,则返回true;否则返回false

 t1 != t2 

 如果两个对象t1和t2类型不同,则返回true;否则返回false

 t.name()

 返回类型的C-style字符串,类型名字用系统相关的方法产生

 t1.before(t2)

 返回指出t1是否出现在t2之前的bool值

 

type_info类提供了public虚析构函数,以使用户能够用其作为基类。它的默认构造函数和拷贝构造函数及赋值操作符都定义为private,所以不能定义或复制type_info类型的对象。程序中创建type_info对象的唯一方法是使用typeid操作符(由此可见,如果把typeid看作函数的话,其应该是type_info的友元)。type_info的name成员函数返回C-style的字符串,用来表示相应的类型名,但务必注意这个返回的类型名与程序中使用的相应类型名并不一定一致(往往如此,见后面的程序),这是由实现所决定的,标准只要求实现为每个类型返回唯一的字符串。

 

 

常用的形式:typeid(常量或变量或表达式).name()   

//获取该常量或变量或表达式的数据类型名对应的字符串

例如 

int  a;     float b;

cout<<typeid(a).name(); //输出结果为变量a的数据类型名: int

cout<<typeid(b).name(); //输出结果为变量b的数据类型名:float

cout<<typeid(‘$’).name(); //输出结果为常量‘$’的数据类型名: char

注意:在c++中,typeid用于获知一个常量或变量的具体类型。(注意:typeid本身是操作符,不是函数!)

 

使用实例

[cpp] view plain copy

  1. //使用typeid(变量或类型).name()来获取常量或变量的类型  
  2. #include <typeinfo>  //使用类型获取函数必须包含此头文件  
  3. #include <iostream>  
  4. using namespace std;  
  5. int main()  
  6. {  
  7.     cout<< "常量1的数据类型:"<<typeid(1).name()<<endl;  
  8.     cout<< "常量1u的数据类型:"<<typeid(1u).name()<<endl;  
  9.     cout<< "常量1l的数据类型:"<<typeid(1l).name()<<endl;  
  10.     cout<< "常量3.14的数据类型:"<<typeid(3.14).name()<<endl;  
  11.     cout<< "常量3.14f的数据类型:"<<typeid(3.14f).name()<<endl;  
  12.     cout<< "常量\'1\'的数据类型:"<<typeid('1').name()<<endl;  
  13.     cout<< "常量\"1\"的数据类型:"<<typeid("1").name()<<endl;   
  14.     return 0;  
  15. }  



 

运行结果

STL标准模板库

C++并没有规定各种数据类型在内存中的存储大小,依赖于不同的编译器的不同而不同,要想获知当前编译器对各种数据类型分配的大小,可以通过sizeof运算符来获取。

使用方法1

sizeof(数据类型)  

使用方法2

sizeof(变量名   常量名 表达式  

sizeofint     

int  a

sizeofa

  1. //数据类型空间分配情况  
  2. #include <iostream>  
  3. using namespace std;  
  4. int main()  
  5. {    
  6.    cout<<"vc++6.0 编译环境下,各种数据类型变量所占的内存空间大小(字节为单位)"<<endl;  
  7.    cout<<"sizeof(int)  "<<sizeof(int)<<endl;  //4
  8.    cout<<"sizeof(short int)  "<<sizeof(short)<<endl;  //2
  9.    cout<<"sizeof(long int)  "<<sizeof(long)<<endl;  //4
  10.    cout<<"sizeof(unsigned int)  "<<sizeof(unsigned)<<endl;  //4
  11.    cout<<"sizeof(unsigned short int)  "<<sizeof(unsigned short)<<endl;  //2
  12.    cout<<"sizeof(unsigned long int)  "<<sizeof(unsigned long)<<endl;  //4
  13.    cout<<"sizeof(char )  "<<sizeof(char)<<endl;  //1
  14.    cout<<"sizeof(float)  "<<sizeof(float)<<endl;  //4
  15.    cout<<"sizeof(double)  "<<sizeof(double)<<endl;  //8
  16.    cout<<"sizeof(long double)  "<<sizeof(long double)<<endl;  //8
  17.    return 0;  
  18. }  

 



2020 jeepxie.net webmaster#jeepxie.net
10 q. 0.007 s.
京ICP备10005923号