目录
一、迭代器
基本概念
迭代器:本质类中类,核心运算符重载
迭代器的分类
正向迭代器:iterator
begin()
end()
反向迭代器reverse_iterator
rbegin()
rend()
常正向迭代器 const_iterator
cbegin()
cend()
常反向迭代器const_reverse_iterator
crbegin()
crend()
按功能分类
正向迭代器
双向迭代器
随机访问迭代器
容器中迭代器分类 一般连续性内存都可用迭代器访问
容器名 迭代器类型
array 随机访问
vector 随机访问
deque 随机
stack、queue、priority_queue 不支持
list 双向
set/multiset 双向
map、multimap 双向
迭代器的辅助函数
移动 advance(iterator iter,n)
间距 distance(iterator begin,iterator end)
交换 iter_swap(iterator first iterator second)
(1)内置迭代器的使用
#include<vector>
int main()
{
vector<int> data = { 1,2,3,4,5,6,7,8,9 };
vector<int>::iterator iter;
//对象模仿指针的行为
for (iter = data.begin();iter != data.end();iter++)
{
cout << *iter << " ";
}
cout << endl;
//迭代器一般都是++操作无--操作
auto rIter = data.rbegin();
for (;rIter != data.rend();rIter++)
{
cout << *rIter << " ";
}
cout << endl;
//区别在于常无法去修改数据
vector<int>::const_iterator c_iter;
for (c_iter = data.cbegin();c_iter != data.cend();c_iter++)
{
cout << *c_iter << " ";
}
cout << endl;
return 0;
}
(2)自己模拟迭代器的实现
通过重载运算符的方式,将对象当指针使用
//节点
template<class _Ty>
struct Node
{
_Ty data;
Node<_Ty>* next;
Node<_Ty>(_Ty data) :data(data), next(nullptr) {}
//用作插入
Node<_Ty>(_Ty data, Node<_Ty>* next) : data(data), next(next) {}
};
//链表 内部包含类中类iterator
template<class _Ty>
class My_List
{
public:
My_List()
{
curSize = 0;
}
//插入节点
void push_front(int data)
{
if (curSize == 0)
{
frontNode = new Node<_Ty>(data);
tailNode = frontNode;
}
else
{
frontNode = new Node<_Ty>(data, frontNode);
}
curSize++;
}
void print()
{
Node<_Ty>* pMove = frontNode;
while (pMove != nullptr)
{
cout << pMove->data << " ";
pMove = pMove->next;
}
}
//迭代器
class iterator
{
public:
iterator(Node<_Ty>* pMove=nullptr) :pMove(pMove) {}
//由于用临时变量赋值,使用拷贝构造
iterator(const iterator& object) :pMove(object.pMove) {}
bool operator!=(const iterator& object) const
{
return this->pMove != object.pMove;
}
iterator operator++(int)
{
pMove = pMove->next;
return iterator(pMove);
}
_Ty operator*()
{
return pMove->data;
}
protected:
Node<_Ty>* pMove;
};
iterator begin()
{
return iterator(frontNode);
}
iterator end()
{
return iterator(nullptr);
}
protected:
Node<_Ty>* frontNode;
Node<_Ty>* tailNode;
int curSize;
};
void testList()
{
My_List<int> list;
list.push_front(1);
list.push_front(2);
list.push_front(3);
list.print();
My_List<int>::iterator iter = list.begin();
for (;iter != list.end();iter++)
{
cout << *iter << " ";
}
cout << endl;
}
(3)流型迭代器
特殊迭代器(流型迭代器) 一般用在辅助打印
输出流型(两种构造方式)
ostream_iterator<_Ty> iter(ostream* out)
ostream_iterator<_Ty> iter(ostream& out,char* str)
输出流型迭代器赋值运算,就是把数据打印
输入流型(两种构造方式)
//构造无参对象,是错误流(输入错误类型返回错误)
istream_iterator<_Ty> iter //*运算等效cin
istream_iterator<_Ty> iter(istream& in)
#include<vector>
void test1()
{
ostream_iterator<int> iter(cout);
iter = 123;//打印到屏幕上
//一般作为别的函数的参数 在打印数据后面
ostream_iterator<int> iter2(cout,"欧拉欧拉");
iter2 = 1432;
vector<int> data = { 1,2,3,4 };
//等效打印
copy(data.begin(), data.end(), ostream_iterator<int>(cout, "\t"));
//输入流型
cout << "测试:" << endl;
istream_iterator<int> end;
istream_iterator<int> in(cin);
vector<int> inputData;
//反复输入 直到输入类型错误
while (in != end)
{
inputData.push_back(*in);
++in;//改变位置 使其能够重复输入
}
for (auto v : inputData)
{
cout << v << " ";
}
cout << endl;
}
二、lambda表达式
(1)基本概念
就是一个返回函数指针的表达式
注意,它的定义和返回函数指针是一起的
组成部分 mutable:是否可以修改 exception:是否有异常
[捕获方式](函数参数)mutable exception->函数返回类型{函数体}
int Max(int a,int b)
{
return a>b?:a,b;
}//完整写法
int(*pMax)(int,int)=[](int a,int b)mutable noexcept->int{return a>b?:a,b;}
省略写法:中间描述词均可以省略
auto ppMax=[](int a,int b){return a>b?:a,b;}
//只需要短暂性局部使用 相当于函数定义声明
//定义函数指针
int(*pMax)(int a, int b) = nullptr;
//函数实现
auto pp = [](int a, int b) {return a > b ? a : b;};
//直接调用
cout << pp(1, 3);
cout << [](int a, int b) {return a > b ? a : b;}(1, 3) << endl;
(2)捕获方式的区别
捕获方式(函数使用外部变量的方式)
[=] 值的方式捕获:如果在函数中修改不会影响到外部变量
[&] 引用的方式捕获:同步到外部变量
[this] 类的方式:捕获类中数据成员
[] 不捕获任何变量
组合方式
[=,&] x用引用的方式,其余用值的方式
class MM
{
public:
void print()
{//表示捕获的是类内的数据
[this] {cout << name << " " << age << endl;}();
}
protected:
string name="mo";
int age=12;
};
int main()
{
int data = 10101;//无参可以省略括号
//1.用值的方式:在lambda不能充当左值,函数1调用不会因为值的改变而改变
//即外界值在改变也不会影响函数
auto pData = [=] {cout << data << endl;};
pData();
data = 8080;
pData();
//2.lambda可以改变值,并且会因为值的改变而改变
auto pData2 = [&] {cout << data << endl;};
//3.this方式
MM mm;
mm.print();
//特殊 结合auto 类似函数模板
auto pAuto = [](auto a, auto b)->auto{return a > b ? a : b;};
cout << pAuto(1, 3);
return 0;
}
三、仿函数 包含头文件functional
基本概念
仿函数 类模仿函数调用行为
实质:无名对象调用重载的函数
一般情况,仿函数做排序准则 或者一些算法的计算准则
关键在于重载()
标准库中的仿函数
算术类
关系类
逻辑类
选择、证明、投射等
使用
#include<map>
class Sum
{
public:
int operator()(int a, int b)const
{
return a + b;
}
protected:
};
int main()
{//自定义实现
//重载()的调用
Sum s;
//显示调用
cout <<"显示调用"<< s.operator()(1, 3) << endl;
cout << "隐式调用" << s(1, 3) << endl;
//类模仿调用的行为 也可用Sum{}(1,3) 主要起标识作用
cout << "无名对象" << Sum()(1, 3) << endl;
//库内部分例子
//算术
cout << plus<int>{}(1, 3) << endl;
//关系
map<int, less<int>> map1;
map<int, greater<int>> map2;
//逻辑类
cout << logical_and<int>{}(1, 3);//&&
return 0;
}
四、函数适配器 包含头文件functional
bind函数绑定
(1)普通函数绑定
以下面例子为例 Max函数有两个参数 ,print函数传入的pMax只有一个参数
使用bind给Max绑定一个参数再传入print
int Max(int a, int b)
{
return a > b ? a : b;
}
void print(int(*pMax)(int), int a)
{
pMax(a);
}
int main()
{
//只是单纯绑定一个参数 并未改变函数指针类型
//std::placeholders::_1占位符
//绑定的函数指针,占位符,参数设置
auto pMax = bind(Max, std::placeholders::_1, 100);//把第二个参数置为100
cout << pMax(1);
cout << pMax(1, 2);//完成绑定后 使用绑定值第二个参数无效
return 0;
}
(2)类内成员函数绑定
class Test
{
public:
void print(int a, int b, int c)
{
cout << a << " " << b << " " << c << endl;
}
};
void testClass()
{
Test test;
auto testFunc = bind(&Test::print, test, std::placeholders::_1, std::placeholders::_2, 100);
//此时调用不需要对象 直接调用
testFunc(1, 3);
}
(3)占位符表示原来的参数去第几位
void printData(int a, Test b, string str)
{
cout << " 调用成功" << endl;
}
//通过占位符,调整参数位置 形成不同调用形态
//占位符表示原来的参数去第几位 1去第三位 Test()去第1位 "as"去第二位
void testExUser()
{
auto testFunc = bind(printData,
std::placeholders::_3, std::placeholders::_1, std::placeholders::_2);
printData(1, Test(), "as");
testFunc(Test(), "as", 1);
}
五、函数包装器 包含头文件functional
一旦函数被包装,函数包装器可以替换函数指针直接调用
函数包装器实例化传参:function<函数返回值类型(参数类型)>
(1)包装普通函数
int Max(int a, int b)
{
cout << "包装普通函数" << endl;
return a > b ? a : b;
}
int main()
{//int返回值类型 (int,int)参数类型
function<int(int, int)> funcMax(Max);
cout << funcMax(1, 3) << endl;
return 0;
}
(2)包装成员函数和静态函数
class MM
{
public:
void print(int a)
{
cout << "包装成员函数" << endl;
}
static void printStatic()
{
cout << "包装静态成员函数" << endl;
}
};
int main()
{
MM mm;
function<void(int)> func(bind(&MM::print, &mm, std::placeholders::_1));
func(1);
function<void()> funcS(MM::printStatic);
funcS();
return 0;
}
(3)包装仿函数
class MM
{
public:
};
class Test
{
public:
void operator()(string str)
{
cout << str << endl;
}
};
int main()
{
Test test;
function<void(string)> func = test;
func("包装仿函数");
return 0;
}
(4)更替参数顺序
class MM
{
public:
};
void printData(int a, MM mm, string str)
{
cout << "bind与function结合" << endl;
}
void testFuncBind()
{
function<void(string, int, MM)> pf = bind(printData,
std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
pf("as", 1, MM());
}