头文件
#include<functional>
1. bind
示例一
void useBindDemo() {
set<int> myset;
myset.insert(3);
myset.insert(4);
myset.insert(5);
vector<int> vec;
transform(myset.begin(), myset.end(), back_inserter(vec), bind(multiplies<int>(), placeholders::_1, 10));
copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
}
示例二
//convert a regular function into functor
double Pow(double x, double y) {
return pow(x, y);
}
void useBindDemo2() {
set<int> myset;
myset.insert(3);
myset.insert(4);
myset.insert(5);
deque<int> d;
//vector<int> d;
auto f = function<double (double, double)>(Pow);
transform(myset.begin(), myset.end(), back_inserter(d), bind(f, placeholders::_1, 2));
// d {9,16,25}
}
将某个容器中某个区间范围的数属于哪个范围
void useBindDemo3() {
set<int> myset;
for (int t = 0; t < 20; t++) {
myset.insert(t);
}
vector<int> d;
transform(myset.begin(), myset.end(), back_inserter(d),
bind(logical_and<bool>(),
bind(greater<int>(), placeholders::_1, 2),
bind(less<int>(), placeholders::_1, 10)));
//d {0 0 0 1 1 1 1 1 1 0 ......}
copy(d.begin(), d.end(), ostream_iterator<int>(cout, " "));
}
2. bind常和this一起使用
通常我们见到bind的时候他通常和std::function或者函数指针差不多。
但是std::function通常说的是某类函数长什么样子,比如输入为两个int返回为bool的可以定义为
using func = std::functiom<bool(int,int)>;
但是如果我我们想用某个具体的函数时,如果使用函数指针可以这样写
bool func_1(int a, int b) { // ... }
void* func_ptr = &func_1;
那么上面的写法实际上可以写成使用bind的
#include <iostream>
#include <functional>
bool func_1(int a, int b) {
bool ret = (a+b) > 0 ? true : false;
return ret;
}
auto func_ptr = std::bind(func_1,std::placeholders::_1, std::placeholders::_2);
我们想想其实上面使用bind和函数指针是没有什么区别的。但是如果在面向对象的编程中,我们使用函数指针就会遇到麻烦。
比如一个函数在类里面,那就是成员函数,而成员函数都是属于某个实例的,如何处理这个this问题,处理成函数指针时,##### 我们可以加上static
关键字给这个函数。
但是有了bind就不一样了。我们可以将this作为参数传入。其实这个也很简单,如果使用过std::thread的人都会看到样大代码,如果使用类的成员函数创建新线程就会传入一个this指针。
说白了,就是要说明,你这个函数到底是那个this指针的函数。
传入this指针至少也分两种,类内使用和类外使用。
2.1 类内使用
auto fun_ptr = std::bind(&类名::函数名,this, _1, _2);
2.2 类外使用
A a; // class A
auto fun_ptr = std::bind(&类名::函数名, &a, _1, _2);
这里如何理解bind和this呢,其实大家如果知道原型模式,甚至更简单的复制构造函数,明白这个就简单。this就是this。
将某个范围的数拷贝到容器中
bool needCopy(int x) {
return (x > 2 && x < 10);
}
void useBindDemo4() {
set<int> myset;
for (int t = 0; t < 20; t++) {
myset.insert(t);
}
vector<int> d;
transform(myset.begin(), myset.end(), back_inserter(d),needCopy);
}
这里我们发现,这拷贝进去的是 0 1 啊,不是我们想要的啊。那我们应该修改啊。自己尝试下吧。
3. lambda
void useLambda() {
set<int> myset;
for (int t = 0; t < 20; t++) {
myset.insert(t);
}
vector<int> d;
transform(myset.begin(), myset.end(), back_inserter(d),
[](int x) {return ((x > 2) && (x < 10)) ? x : 0; });
}
3.1 lambda函数[=] [&]
这个很简单
[=] 是值拷贝,就是如果使用到当前环境中的变量,就是值拷贝。什么叫值拷贝。
这个刚学习c的函数就有
void add(int a) { a++;}
int main() {
int a = 1;
add(a);
}
a不会因为调用add函数就改变自身在main中的值。
而[&]就是引用拷贝,顾名思义,就是用的数据本身。
什么时候会用到{}这种函数呢,就是不想创建新的函数或者这个函数比较简单。
举个不想创建的新的函数的例子。
比如你写得某个函数只会用到一次,你就不应该想着把这个单独隔离成一个函数。
在比如说这个函数就只有几行代码,比如重写sort函数时,我想比较两个值的大小让后按照从小到大的顺序排列。
sort(a.begin(), a.end(), [](int b, int c) { return b < c; });
原文链接: https://www.cnblogs.com/cyssmile/p/12803641.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;
也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/345157
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!