绑定器和函数对象
-
- bind1st/bind2nd简单用法
- bind1st/bind2nd底层实现
- function函数保留类型
- function应用
bind1st/bind2nd简单用法
#include <iostream>
#include <vector>
#include <algorithm>
#include<functional>
#include <ctime>
using namespace std;
/*
绑定器和函数对象(对象有小括号运算符重载函数)
1.C++ STL中的绑定器
bind1st 把函数对象operator()第一个参数 绑定成一个确定的值
bind2nd 把函数对象operator()第二个参数 绑定成一个确定的值
2.bind 绑定器 和function函数对象机制 C++11从boost库中引入的机制
3.lambda 表达式 底层依赖函数对象机制实现
*/
template<typename Container>
void showContainer(Container conn)
{
//使用typename告知Container作用域后面是一个类型 而不是变量
//类型可以定义变量 但是变量本身不能定义变量
typename Container::iterator it = conn.begin();
for (; it != conn.end(); ++it)
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
vector<int> vec;
srand(time(nullptr));
for (int i = 0; i < 20; ++i)
{
vec.push_back(rand() % 100 + 1);
}
//泛型算法sort 默认从小到大排序 传入起始末尾迭代器
showContainer(vec);
sort(vec.begin(), vec.end());
showContainer(vec);
//great 是一个二元函数对象 小括号运算符重载函数有两个对象
sort(vec.begin(), vec.end(), greater<int>());
//将70按照顺序插入到容器当中 找第一个小于70的元素,从容器中拿一个数和70进行比较
//operator()(const &val)
//greater a > b
//less a < b
//绑定器 + 二元函数对象 = 间接变成了一元函数对象
//bind1st:bool operator()(const _Ty& _Left, const _Ty& _Right)
// bool operator()(70, const _Ty& _Right)
//bind2nd
auto it1 = find_if(vec.begin(), vec.end(), bind1st(greater<int>(), 70));
auto it2 = find_if(vec.begin(), vec.end(), bind1st(less<int>(), 70));
if (it1 != vec.end())
{
vec.insert(it1, 70);
}
return 0;
}
bind1st/bind2nd底层实现
template<typename Iterator, typename Compare>
Iterator my_find_it(Iterator first, Iterator last, Compare comp)
{
for (; first != last; ++first)
{
//comp.operator()(*first)
if (comp(*first))
{
return first;
}
}
return last;
}
template<typename Compare,typename T>
class _mybind1st
{
public:
_mybind1st(Compare comp, T val)
:_comp(comp)
, _val(val)
{
}
bool operator()(const T& second)
{
return _comp(_val, second);
}
private:
Compare _comp;
T _val;
};
//mybind1st (greater<int>(),70)
template<typename Compare , typename T>
_mybind1st<Compare,T> mybind1st(Compare comp, const T& val)
{
//直接使用函数模板,好处是,可以进行推演
//根据实参,推演出函数对象和元素类型推演出来
return _mybind1st<Compare, T>(comp, T);
}
function函数保留类型
#include <iostream>
#include <vector>
#include <algorithm>
#include<functional> //使用function函数对象类型
#include <ctime>
#include <string.h>
using namespace std;
/*
bind 绑定器和函数对象
C++ STL bind1st/bind2nd 本身还是一个函数对象
function:绑定器,函数对象,lambda表达式 他们只能使用在一条语句中
*/
void hello1()
{
cout << "hello world" << endl;
}
void hello2(string str)
{
cout << str << endl;
}
int sum(int a, int b)
{
return a + b;
}
class Test
{
public:
//调用普通函数和成员函数方法的一大区别
//调用普通的函数只需要函数名,但是调用成员方法需要依赖对象,this指针
//函数指针 void (*pfunc)(string str)
//成员方法 void (Test::*pfunc)(string str)
void hello(string str)
{
cout << hello << endl;
}
private:
};
int main()
{
/*
1.通过函数类型实例化function
2.通过function调用operator()函数的时候,需要根据函数类型传入相应的参数
*/
//function的类模板定义处,看到希望用函数类型实例化类模板function
//void(*)() 指向一个返回值为void,不带形参的函数
//函数类型 只给出返回值和参数列表
//用函数对象类型 把函数类型保留下来
//func1.operator() 再调用里面包装的 hello1()函数
function<void()> func1 = hello1;
function<void()> func2(hello1);
function<void(string)> func3 = hello2;
//func3.operator()(string str) =>
func3("hello hello3");
func1();
function<int(int, int)> func4 = sum;
cout << func4(20, 30) << endl;
function<int(int, int)> func5 = [](int a, int b)->int {return a + b; };
cout << func5(100, 50) << endl;
function<void(Test*, string)> func6 = &Test::hello;
//第一个参数传入一个临时对象
func6(&Test(), "Hello func6");
return 0;
}
function应用
#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
#include<functional> //使用function函数对象类型
#include <ctime>
#include <string.h>
using namespace std;
/*
bind 绑定器和函数对象
C++ STL bind1st/bind2nd 本身还是一个函数对象
function:绑定器,函数对象,lambda表达式 他们只能使用在一条语句中
*/
void doShowAllBooks() { cout << "查看所有书籍信息" << endl; }
void doBorrow() { cout << "借书" << endl; }
void doBack() { cout << "还书" << endl; }
int main()
{
int choice = 0;
map<int, function<void()>> actionMap;
actionMap.insert({ 1,doShowAllBooks });
actionMap.insert({ 2,doBorrow });
actionMap.insert({ 3,doBack });
for (;;)
{
cout << "__________________" << endl;
cout << "1.查看所有书籍信息" << endl;
cout << "2.借书" << endl;
cout << "3.还书" << endl;
cout << "4.查询书籍" << endl;
cout << "5.注销" << endl;
cout << "__________________" << endl;
cout << "请选择" << endl;
cin >> choice;
//switch case 无法闭合做到开闭原则 随着选项发增加和删除就要
auto it = actionMap.find(choice);
if (it == actionMap.end())
{
cout << "输入数字无效" << endl;
}
else
{
it->second();
}
}
}