STL迭代器 算法 函数对象
迭代器
- 迭代器是STL组件中的纽带.
- 迭代器相当于一个统一的接口, 对外的统一标准.
- 通过迭代器将我们的STL组合在一起, 形成灵活而强大的功能
- 每个容器的迭代器都是不同的.
- 迭代器有
随机访问迭代器,双向迭代器等.
分类
输入迭代器
- 只读,一次传递
- 一个输入迭代器仅能对它所选择的每个元素进行一次解析, 它们只能向前移动.
- 定义了一个超越末尾的值作为结尾.
输出迭代器
- 只写,一次传递
- 只能对每个写出的值进行一次解析, 并且只能向前移动.
前向迭代器
- 前向迭代器包含了输入和输出迭代器两者的功能
- 可以多次解析一个迭代器指定的位置
- 可以对一个值进行多次读/写
- 前向迭代器只能向前移动
双向迭代器
- 具有前向迭代器的全部功能
- 可以利用自减操作符operator--向后一次移动一个位置
随机访问迭代器
- 具有双向迭代器的所有功能
- 拥有指针的大部分功能
- 可以像一个指针那样可以进行操作
- 可使用操作符operator[]
| 迭代器类别 | 说明 |
|---|---|
| 输入迭代器 | 从容器中读取元素。输入迭代器只能一次读入一个元素向前移动,输入迭代器只支持一遍算法,同一个输入迭代器不能两遍遍历一个序列 |
| 输出迭代器 | 向容器中写入元素。输出迭代器只能一次一个元素向前移动。输出迭代器只支持一遍算法,统一输出迭代器不能两次遍历一个序列 |
| 正向迭代器 | 组合输入迭代器和输出迭代器的功能,并保留在容器中的位置 |
| 双向迭代器 | 组合正向迭代器和逆向迭代器的功能,支持多遍算法 |
| 随机访问迭代器 | 组合双向迭代器的功能与直接访问容器中任何元素的功能,即可向前向后跳过任意个元素 |
- 每种迭代器均可进行包括表中前一种迭代器可进行的操作
- 迭代器的操作本质上是通过重载运算符来实现的
- 迭代器支持何种操作和能够执行什么运算是由迭代器所重载的运算符来决定的
| 迭代器类型 | 操作类型 | 说明 |
|---|---|---|
| 所有迭代器 | p++ <br/> ++p | 后置自增迭代器 <br/>前置自增迭代器 |
| 输入迭代器 | *p <br/> p=p1 <br/> p==p1 <br/> p!=p1 | 复引用迭代器,作为右值 <br/> 将一个迭代器赋给另一个迭代器 <br/> 比较迭代器的相等性 <br/> 比较迭代器的不等性 |
| 输出迭代器 | *p <br/> p=p1 <br/> | 复引用迭代器,作为左值 <br/> 将一个迭代器赋给另一个迭代器 |
| 正向迭代器 | 提供输入输出迭代器的所有功能 | |
| 双向迭代器 | --p <br/> p-- | 前置自减迭代器 <br/> 后置自减迭代器 |
| 随机访问迭代器 | p+=i <br/> p-=i <br/> p+i <br/> p-i <br/> p[i] <br/> p<p1 <br/> p<=p1 <br/> p>p1 <br/> p>=p1 | 将迭代器递增i位 <br/> 将迭代器递减i位 <br/> 在p位加i位后的迭代器 <br/> 在p位减i位后的迭代器 <br/> 返回p位元素偏离i位的元素引用 <br/> 如果迭代器p的位置在p1前,返回true,否则返回false <br/> p的位置在p1的前面或同一位置时返回true,否则返回false <br/> 如果迭代器p的位置在p1后,返回true,否则返回false <br/> p的位置在p1的后面或同一位置时返回true,否则返回false <br/> |
算法
#include <iostream>
#include <vector>
#include <algorithm>
template <typename T>
void Foo(T tNum)
{
std::cout << tNum << std::endl;
}
int main()
{
std::vector<int> vi;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);
vi.push_back(4);
vi.push_back(5);
vi.push_back(6);
vi.push_back(7);
vi.push_back(8);
// 通过迭代器操作容器
std::vector<int>::iterator it;
// 遍历容器
for (it = vi.begin(); it != vi.end(); ++it)
{
std::cout << *it << std::endl;
}
// 使用算法
std::for_each(vi.begin(), vi.end(), Foo<int>);
return 0;
}
for_each 函数, 通过迭代器, 遍历了容器.
GP(模板编程/泛型编程)和OOP(面向对象)
GP和OOP是背道而驰的
我们的STL如下图所示:
可以看到, 我们STL中的每个组件都是分开的.
组件和组件之间像积木一样搭建成了我们的STL.
而如果我们使用OOP的思想来设计, 会得到下图: 
注意事项
- 我们的
模板对象并不是真正存在的, 它只是一个工厂 - 必须有原料, 才能有产品.
- 我们必须进行
显式的调用, 才能编译出来我们的真正的模板对象.
函数对象
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> vi;
vi.push_back(1);
vi.push_back(2);
vi.push_back(3);
vi.push_back(4);
vi.push_back(5);
vi.push_back(6);
vi.push_back(7);
vi.push_back(8);
// 统计一下有多少个>5的元素
// 为了多用函数 做的一个示范
int nResult = std::count_if(vi.begin(), vi.end(),
std::not1( std::bind2nd( std::less<int>(), 5 ) ) );
return 0;
}
- 函数对象是一个类
- 函数对象可以当函数来用
- 它重载了
operator() - 我们称之为 _函数对象_, 或者 _仿函数_.
未完待续...
如有错误,请提出指正!谢谢.
本文由 花心胡萝卜 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: 2017-04-13 at 04:14 pm