一、template 编程和迭代器粗解

1.1 实验内容

本节内容主要讲述 c++11 模板的用法,以后的代码中会大量的用到模板的知识。同时简单讲解迭代器的相关知识,为后面容器和算法的内容作铺垫。

1.2 实验知识点

  • 模板编程
    • 基本语法
    • 模板函数
    • 类模板和成员模板
    • 模板类中的静态成员
    • typename和class
  • 迭代器
    • 迭代器详解
    • 迭代器种类和使用
 

基本语法

模板编程是 STL 的基石,也是 c++11 的核心特性之一。模板是相对于编译器而言,顾名思义就是向编译器提供一个处理事务的模板,以后需要处理的东西,如果都是这个事务类型,那么统统用这个模板处理。
三、函数模板
模板的基本语法如下:
template <typename/class T>
template 告诉编译器,接下来是一个模板 ,typename 和 class 都是关键字,在这里二者可以互用没有区别。在< >中 T 叫做模板形参,一旦模板被实例化,T 也会变成具体的类型。接下来,我们看一个例子。
 
代码实例:
template <typename T>
T add(const T lva ,const T rva)
{
T a ;
a = lva + rva ;
return a;
}

这是一个模板函数的简单实例,所有模板函数在开始都需要 template 语句,以告诉编译器这是一个模板和参数等必要信息,当然里面的 T 可以取任意你喜欢的名字 ,模板参数个数也是任意更换的。 还要提醒的一点是:template <typename T1 ,typename T2 = int>函数模板是支持默认参数的,T1 、T2顺序在默认情况下是可以任意的,不用严格按照从右到左的顺序。
然后就是使用了,我们可以写出add(1,2) 这样的函数,也可以写出add(2.5,4.6)这样的函数,向 add 函数提供参数时,编译器会自动分析参数的类型,然后将所有用到 T 定义的换成相对性的类型,以上的两个函数在编译期间会生成
int add(const int lva ,const int rva)
{
int a ;
a = lva + rva ;
return a;
}

double add(const double lva ,const double rva)
{
double a ;
a = lva + rva ;
return a;
}

这样的两个具体函数。如果我们使用add(1,2.0)是会报错的,编译器无法找到add(int,double)。大家可以自己分析一下为什么。
 
四、类模板和成员模板
 

类模版

c++11 不仅支持对函数的模板化,也支持对类的模板,下面来看基本的语法是怎样的:
template <class T>
class Myclass
{
T a;
public:
T add(const T lva ,const T rva);
};
template <class T>
T Myclass<T>::add(const T lva, const T rva)
{
a = lva + rva;
return a;
}

这是一个简单并且典型的类模板,在程序中给出模板并不能使用它,还必须实例化,比如:
Myclass<int> A; //用 int 实例化一个类A
Myclass<double> B; //用 double 实例化一个类B
当程序编译到这里时就会按照我们给出的类型,声明两组类和两组类函数。注意,在这里我们一定要显式给出类型 T 。类模板不像是函数模板 ,函数模板会根据参数推断类型。 当然类模板也支持默认参数,但是类模板必须严格从右往左默认化。

成员模板

模板的使用范围是广泛的,不仅可以用作函数模板,类模板,还可以用作 class ,struct ,template class 的成员。而要实现 STL 这是我们必须掌握和使用的特性。我们先看一个简单的例子,用上面的类改编而来:
template <class T>
class Myclass
{
public:
T a;
template <typename type_1 , typename type_2>
type_1 add(const type_1 lva ,const type_2 rva);
};
template <class T>
template <typename type_1,typename type_2>
type_1 Myclass<T>::add(const type_1 lva, const type_2 rva)
{
a = lva + rva;
return a;
}

在类的声明中使用了一个嵌套的模板声明。且通过作用域运算符 :: 指出 add 是类的成员,需要注意的一点,有些编译器不支持模板成员,而有些编译器不支持在类外定义。我们默认大家的编译器都支持。模板如此强大,甚至允许我们在模板类中再建立模板类:
template <class T>
class Myclass
{
public:
T a;
template <typename type_1 , typename type_2>
type_1 add(const type_1 lva ,const type_2 rva);
template <class type_3>
class Myclass_2; // 声明放在这里,具体定义放在类外进行。
Myclass_2<T> C; // 定义一个Myclass_2 类 A。使用 T 进行实例化
};
template <class T>
template <typename type_1,typename type_2>
type_1 Myclass<T>::add(const type_1 lva, const type_2 rva)
{
a = lva + rva;
return a;
}
template <class T>
template <class type_3>
class Myclass<T>::Myclass_2
{
public:
type_3 value;
type_3 sub(const type_3 a , const type_3 b) {vlaue = a - b;}
};

当然我们暂时还用不到这样复杂的东西,这里只是展现了模板的部分特性。
 
 
五、模板类中的静态成员
 
 
我们知道,在类中定义的静态成员是存储在静态区中,被所有类对象共享,并不属于某一个类所有,同样的在模板类中的静态成员也不会被复制多份,而是被同类实例化的类对象共享,比如所有 int 和所有 double 的类对象,享有相互独立的静态变量。也可以说是编译器生成了 int 和 double 两个版本的类定义。
 
六、typename 和 class
 
typename和class是模板中经常使用的两个关键词 ,在模板定义的时候没有什么区别。以前用的是 class,后来 c++ 委员会加入了 typename。因为历史原因,两个是可以通用的。对有些程序员来说,在定义类模板的时候,常常使用 class 作为关键字,增加代码可读性。其它则用 typename,上面的代码大都遵循这样的标准,但是并无强制规定。但是如果二者没有差别,为什么还要加入typename呢?c++标准委员会不会增加无用的特性,让我们来看一个例子:
class Myclass{
public:
Myclass();
typedef int test; //定义类型别名
}
template <class T>
class Myclass2{
public:
Myclass2();
T::test *a // 声明一个指向T::test类型的指针。
// typename T::test * a
}

以上的代码没有全部写完,大家觉得编译器能够过吗?答案是不能,因为在 c++ 中,允许我们在类中定义一个类型别名,且使用的时候和类名访问类成员的方法一样。这样编译器在编译的时候就会产生二义性,它根本不知道这是一个类型还是别名,所以我们加上 typename 显式说明出来。当然如果这里没有二义性,比如Myclass ::test * a ,加上 typename 是会报错的。此外,在 class 的 STL 底层还有一个特性,用于保留模板参数,但是在 c++17 中已经舍弃,所以我们没有讲。
 
 
七、实验总结
 
模板是 c++ 最重要的特性之一,模板函数、模板类、类中的模板函数、类中的模板类、模板类中的模板类等等,可以写出太多强大的代码,这也是模板的魅力所在,而 STL 就是基于模板的,大家一定要掌握模板的基本用法。
引用《c++ primer》, 《STL 源码解析》
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

转载于:https://www.cnblogs.com/hx97/p/11192953.html

C++ 实现 STL 标准库和算法(二)template 编程和迭代器粗解 实验楼笔记相关推荐

  1. C++拾取——使用stl标准库实现排序算法及评测

    今天看了一篇文章,讲各种语言的优势和劣势.其中一个观点:haskell非常适合写算法,因为使用者不用去关心具体的计算机实现,而只要关注于操作语义.这让它在专心研究算法的人中非常受欢迎.所以很多时候,语 ...

  2. 【侯捷】C++STL标准库与泛型编程(第二讲)

    第二讲 应具备的基础 C++基本语法 模板(Template)基础 令你事半功倍 数据结构(Data Structures)和算法(Algorithms)概念 令你如鱼得水 书籍: <Algor ...

  3. C++ - STL标准库

    1.C++ STL标准库简介 长久以来,软件界一直希望建立一种可重复利用的东西,以及一种得以制造出"可重复运用的东西" 的方法,从函数(functions),类别(classes) ...

  4. C++STL标准库学习笔记(一)sort

    目录 前言: 正文 一.排序(sort) 用法1:对基本类型的数组(int,double,char...)从小到大排序 用法2:对元素类型为T的基本类型数组从大到小排序: 用法3:用自定义的排序规则, ...

  5. C++STL标准库学习总结/索引/学习建议

    前言: 如果刚刚开始学习STL标准库,不知道从哪里入手学习的话,建议去中国大学mooc平台,先学习北京大学郭炜老师的<程序设计与算法(一)C语言程序设计>(https://www.icou ...

  6. 【侯捷】C++STL标准库与泛型编程(第三讲)

    第三讲 算法的形式 C++标准库的算法,是什么东西? 说明: 算法Algorithm 是个 function template,标准库中的算法都长成如下这样: template<typename ...

  7. STL标准库及泛型编程

    1-认识headers.版本.重要资源 C++ Standard Library Standard Template Library 标准库 > STL 标准库以header files形式呈现 ...

  8. 侯捷C++课程笔记03: STL标准库与泛型编程

    本笔记根据侯捷老师的课程整理而来:STL标准库与泛型编程 pdf版本笔记的下载地址: 笔记03_STL标准库与泛型编程,排版更美观一点(访问密码:3834) 侯捷C++课程笔记03: STL标准库与泛 ...

  9. STL标准库-容器-set与map

    STL标准库-容器-set与multiset C++的set https://www.cnblogs.com/LearningTheLoad/p/7456024.html STL标准库-容器-map和 ...

最新文章

  1. 数据库之子查询四(多重,表复制)
  2. 守望者的逃离—贪心算法
  3. Https协议基本分析
  4. P3201-[HNOI2009]梦幻布丁【启发式合并,链表】
  5. 聚合函数查询 group by having
  6. DSB2017第一名代码尝试运行(记录自用)(一)
  7. 等级考试(一):三级网络---似曾相识
  8. 51Nod-1087 1 10 100 1000【模拟】
  9. 《构建之法》阅读笔记05
  10. 电子信息工程求职目标_广东海洋大学电子与信息工程学院电子信息工程专业欢迎你...
  11. CentOS系统配置 iptables防火墙
  12. java学习血泪史目录
  13. 那些被苏宁奖励的人、重用的人
  14. htmL生日烟花如何加文字,朋友圈发烟花配文字文案
  15. 为什么要用同花顺程序化交易接口?
  16. [Android开发] Xposed 插件开发之三: 编写广告去除插件
  17. 星辰大海,不属于任何人,也属于任何人
  18. 故障码(DTC)状态解析
  19. 基于STM32的智能小车方案设计
  20. 什么是openshift

热门文章

  1. bootstrap学习(四)表格
  2. [小程序]微信小程序登陆并获取用户信息
  3. 数列分块入门3(查询前驱)
  4. PureXXX使用手记
  5. 14.5.3 Locks Set by Different SQL Statements in InnoDB
  6. int (*p)[4] 与 int* p[4]
  7. [算法 笔记]堆排序(续)
  8. POJ3265 Problem Solving ——动态规划——Pku3265
  9. 28 | 案例篇:一个SQL查询要15秒,这是怎么回事?
  10. s5-15 开放的最短路径优先_OSPF