当前位置: 首页 > news >正文

站长工具seo推广汕头网站推广

站长工具seo推广,汕头网站推广,wordpress采集优酷视频,莱芜杂谈c11之前&#xff0c;STL中提供了bind1st以及bind2nd绑定器 首先来看一下他们如何使用&#xff1a; 如果我们要对vector中的元素排序&#xff0c;首先会想到sort&#xff0c;比如&#xff1a; void output(const vector<int> &vec) {for (auto v : vec) {cout <&l…

c++11之前,STL中提供了bind1st以及bind2nd绑定器
首先来看一下他们如何使用:
如果我们要对vector中的元素排序,首先会想到sort,比如:

void output(const vector<int> &vec)
{for (auto v : vec) {cout << v << " ";}cout << endl;
}int main() {vector<int> vec;srand(time(nullptr));for (int i = 0; i < 20; i++) {vec.push_back(rand() % 100 + 1);}output(vec);sort(vec.begin(), vec.end());output(vec);//greater 从大到小排序sort(vec.begin(), vec.end(), greater<int>());output(vec);//less 从小到大排序sort(vec.begin(), vec.end(), less<int>());output(vec);return;
}

sort最后一个参数传入的greater或less都被称为函数对象,顾名思义,表现像函数的对象,因为他们的调用都是在后面加上"()"。
其实这是因为他们都重载了operator()。
来看下greater的定义:

template<class _Ty = void>struct greater{	// functor for operator>_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool result_type;constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const{	// apply operator> to operandsreturn (_Left > _Right);}};

可以看到确实重载了operator(),需要传入两个参数,所以它还是一个二元函数对象。函数对象的概念至关重要!
那什么时候会用到bind1st、bind2nd呢?
比如我们现在要找到第一个小于70的位置,插入70。
可以使用find_if:

	auto it1 = find_if(vec.begin(), vec.end(),bind1st(greater<int>(), 70));if (it1 != vec.end()) {vec.insert(it1, 70);}

这里使用bind1st(greater<int>(), 70)作为find_if的第三个参数,bind1st的作用,首先,将70绑定到二元函数对象(greater)的第一个参数上,其次,将二元函数对象(greater)转为一元函数对象(因为70已知了),传入到find_if的第三个参数中。这便是他的应用场景,或者还可以使用bind2nd和less的搭配:

	auto it1 = find_if(vec.begin(), vec.end(),bind2nd(less<int>(), 70));if (it1 != vec.end()) {vec.insert(it1, 70);}

关于bind1st(greater(), 70)和bind2nd(less(), 70)的理解
因为我们要找小于70的位置,所以,
对于greater来说,left > right,所以绑定到第一个位置
对于less来说,left < right,所以绑定到第二个位置

理解了绑定器后,再来看看function
function需要一个函数类型进行实例化:

void hello1()
{cout << "hello world!" << endl;
}void hello2(string str)
{cout << str << endl;
}class Test
{
public:void hello(string str) { cout << str << endl; }
};int main() {function<void()> func1 = hello1;//function<void()> func1(hello1);func1();//func1.operator() => hello1();function<void(string)> func2 = hello2;func2("gao");//func2.operator()(string str) => hello2(str);function<int(int, int)> func3 = [](int a, int b) -> int { return a + b; };cout << func3(100, 200) << endl;//通过function调用类的成员方法function<void(Test*, string)> func5 = &Test::hello;func5(&Test(), "call Test::hello!");return 0;
}

对function的调用,实际上是调用了function的()重载,从而调用原函数。上面的例子中可以看到lambda表达式也可以通过function调用。这其实就说明了function的真正用途:保存函数对象的类型,也是对函数对象的封装。这也是它和c语言的函数指针的区别(lambda无法通过函数指针调用)。

现在有这样一个场景:
两(多)个函数,有大部分的代码都是一样的,其中只有一两行代码有不一样的地方,我们可以对这个不一样的地方,使用function做一个抽象,比如:
有两个vector打印函数,一个打印模5=0的元素,一个打印大于10的元素:

void print(vector<int> &number, function<bool(int)> filter) {for (const int &i : number) {if (filter(i)) {cout << i << endl;}}
}print(numbers, [](int i){ return i % 5 == 0; });
print(numbers, [](int i){ return i > 10; });

这样就不用定义两个不同的打印函数了。

关于闭包的概念:
下面是维基百度对于闭包的定义:
在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数。 这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。

简单来说:闭包可以记忆住创建它时候的那些变量。
下面,我们再通过一个例子来说明。
现在,假设我们的需求是:获取一个集合中最小和最大值,并在稍后的时候(可能是另外一个函数中)打印它们。 这里,我们常规的做法通常是:通过一个函数获取集合的最大,最小值,然后保存住,最后在需要的时候访问这两个值,然后打印它们。
这样做就会需要解决:如何保存和传递最大,最小这两个值。
但实际上,这里我们可以考虑用闭包来实现这个功能,让闭包把最大,最小两个值捕获下来,然后在需要的地方调用就可以了。

请看一下下面这段代码:

void getMinMax(vector<int>& number, function<void ()>& printer) {int min = number.front();int max = number.front();for (int i : number) {if (i < min) {min = i;}if (i > max) {max = i;}}printer = [=] () {cout << "min:" <<min<< endl;cout << "max:" << max << endl;};
}

这里,我们通过function<void ()>& printer传递出这个闭包。 然后,在需要的地方,这样即可:

function<void()> printer;
getMinMax(numbers, printer);
......printer();

这里的printer其实是我们前面从getMinMax函数出传出的闭包,这个闭包捕获了min和max。我们直接传递这个闭包给需要的地方使用,而不用传递裸的两个数值,是不是优雅的不少?

bind

/*
c++11 bind绑定器 -> 返回的结果还是一个函数对象
*/void hello(string str) { cout << str << endl; }
int sum(int a, int b) { return a + b; }class Test 
{
public:int sum(int a, int b) { return a + b; }
};int main()
{bind(hello, "hello, bind!")();cout << bind(sum, 10, 20)() << endl;cout << bind(&Test::sum, Test(), 20, 30)() << endl;//参数占位符 绑定器出了语句,无法继续使用bind(hello, placeholders::_1)("hello bind 2!");cout << bind(sum, placeholders::_1, placeholders::_2)(200, 300) << endl;//此处把bind返回的绑定器binder就复用起来了function<void(string)> func1 = bind(hello, placeholders::_1);func1("hello gao");return 0;
}

使用bind和function的线程池例子:

class Thread
{
public://接收一个函数对象,参数都绑定了,所以不需要参数Thread(function<void()> func) : _func(func) {}thread start(){thread t(_func);return t;}
private:function<void()> _func;
};class ThreadPool
{
public:ThreadPool() {}~ThreadPool() {for (int i = 0; i < _pool.size(); i++) {delete _pool[i];}}void startPool(int size){for (int i = 0; i < size; i++) {//成员方法充当线程函数,绑定this指针_pool.push_back(new Thread(bind(&ThreadPool::runInThread, this, i)));}for (int i = 0; i < size; i++) {_handler.push_back(_pool[i]->start());}for (thread &t : _handler) {t.join();}}
private:vector<Thread*> _pool;vector<thread> _handler;void runInThread(int id) {cout << "call runInThread! id:" << id << endl;}
};int main()
{ThreadPool pool;pool.startPool(10);return 0;
}

lambda(匿名函数对象)
lambda表达式的语法

[捕获外部变量](形参列表)->返回值{操作代码};[]:表示不捕获任何外部变量
[=]:表示以传值的方式捕获外部的所有变量
[&]:表示以传引用的方式捕获外部的所有变量
[this]:捕获外部的this指针
[=,&a]: 表示以传值的方式捕获外部的所有变量,但是a变量以传引用的方式捕获
[a,b]:表示以值传递的方式捕获外部变量a和b
[a,&b]:a以值传递捕获,b以引用捕获

使用举例:

int main()
{auto func1 = []()->void {cout << "hello world!" << endl; };func1();//[]:表示不捕获任何外部变量//编译报错/*int a = 10;int b = 20;auto func3 = [](){int tmp = a;a = b;b = tmp;};*///以值传递a,b,lambda实现的重载函数operator()中,是const方法,不能修改成员变量//如果一定要修改,将lambda修饰成mutable,但是这并不会改变a的值,因为这是值传递//int a = 10;//int b = 20;//auto func3 = [a, b]() /*mutable*///{//	int tmp = a;//	a = b;//	b = tmp;//};vector<int> vec;vec.push_back(1);vec.push_back(2);vec.push_back(3);for_each(vec.begin(), vec.end(), [](int a) {cout << a << endl;});return 0;
}
class Data
{
public:Data(int a, int b) : ma(a), mb(b) {}int ma;int mb;
};int main()
{map<int, function<int(int, int)>> caculateMap;caculateMap[1] = [](int a, int b)->int {return a + b; };caculateMap[2] = [](int a, int b)->int {return a - b; };cout << caculateMap[1](1, 2) << endl;//智能指针自定义删除器unique_ptr<FILE, function<void(FILE*)>>ptr1(fopen("data.txt", "w"), [](FILE *pf) { fclose(pf); });//优先队列using FUNC = function<bool(Data&, Data&)>;priority_queue<Data, vector<Data>, FUNC>maxHeap([](Data &d1, Data &d2)->bool{return d1.mb > d2.mb;});maxHeap.push(Data(10, 20));return 0;
}

lambda表达式是如何实现的?
其实是编译器为我们了创建了一个类,这个类重载了(),让我们可以像调用函数一样使用。所以,你写的lambda表达式和真正的实现,是这个样子的:
在这里插入图片描述
而对于捕获变量的lambda表达式来说,编译器在创建类的时候,通过成员函数的形式保存了需要捕获的变量,所以看起来是这个样子:
在这里插入图片描述
似乎也没有什么神奇的地方。但正是由于编译器帮我们实现了细节,使我们的代码变得优雅和简洁了许多。

参考文章:https://paul.pub/cpp-lambda-function-bind/


文章转载自:
http://hydrokinetic.ncmj.cn
http://rebeldom.ncmj.cn
http://brummie.ncmj.cn
http://tinpot.ncmj.cn
http://keratometer.ncmj.cn
http://aquicolous.ncmj.cn
http://juglandaceous.ncmj.cn
http://satiric.ncmj.cn
http://lioness.ncmj.cn
http://intracerebral.ncmj.cn
http://plangorous.ncmj.cn
http://anticlimactic.ncmj.cn
http://enjoinder.ncmj.cn
http://avirulence.ncmj.cn
http://tricolour.ncmj.cn
http://advertizing.ncmj.cn
http://bighearted.ncmj.cn
http://armada.ncmj.cn
http://pataca.ncmj.cn
http://rnr.ncmj.cn
http://aplomb.ncmj.cn
http://quizee.ncmj.cn
http://digitorium.ncmj.cn
http://withal.ncmj.cn
http://carbuncular.ncmj.cn
http://moraceous.ncmj.cn
http://arthralgic.ncmj.cn
http://zonky.ncmj.cn
http://rallymaster.ncmj.cn
http://guardhouse.ncmj.cn
http://kotow.ncmj.cn
http://ombudsman.ncmj.cn
http://primly.ncmj.cn
http://londoner.ncmj.cn
http://firemaster.ncmj.cn
http://ileostomy.ncmj.cn
http://inebriate.ncmj.cn
http://coleorhiza.ncmj.cn
http://bandolero.ncmj.cn
http://lignitoid.ncmj.cn
http://amanita.ncmj.cn
http://carbonization.ncmj.cn
http://heartache.ncmj.cn
http://calamitously.ncmj.cn
http://quadrat.ncmj.cn
http://colony.ncmj.cn
http://glide.ncmj.cn
http://deliberately.ncmj.cn
http://commandable.ncmj.cn
http://unreasonably.ncmj.cn
http://yenbo.ncmj.cn
http://heptarchy.ncmj.cn
http://autogravure.ncmj.cn
http://subtilisin.ncmj.cn
http://practicum.ncmj.cn
http://menotaxis.ncmj.cn
http://intuitive.ncmj.cn
http://background.ncmj.cn
http://landsraad.ncmj.cn
http://bumrap.ncmj.cn
http://residua.ncmj.cn
http://appetite.ncmj.cn
http://prosobranch.ncmj.cn
http://hayshaker.ncmj.cn
http://limpidly.ncmj.cn
http://proteinic.ncmj.cn
http://inthronization.ncmj.cn
http://scientism.ncmj.cn
http://ungenerous.ncmj.cn
http://fortaleza.ncmj.cn
http://superconduct.ncmj.cn
http://matriculate.ncmj.cn
http://telephonograph.ncmj.cn
http://cup.ncmj.cn
http://myoneural.ncmj.cn
http://tumefacient.ncmj.cn
http://behaviourism.ncmj.cn
http://outwards.ncmj.cn
http://coenesthesia.ncmj.cn
http://metasilicate.ncmj.cn
http://homomorphic.ncmj.cn
http://sheepwalk.ncmj.cn
http://honeyfuggle.ncmj.cn
http://supple.ncmj.cn
http://sonograph.ncmj.cn
http://dageraad.ncmj.cn
http://surnominal.ncmj.cn
http://calabash.ncmj.cn
http://retardant.ncmj.cn
http://agro.ncmj.cn
http://mesodontism.ncmj.cn
http://cryptogenic.ncmj.cn
http://squiggly.ncmj.cn
http://sculptural.ncmj.cn
http://lick.ncmj.cn
http://pancosmism.ncmj.cn
http://fibrinolysis.ncmj.cn
http://coloratura.ncmj.cn
http://acraldehyde.ncmj.cn
http://confiscatory.ncmj.cn
http://www.dt0577.cn/news/92148.html

相关文章:

  • 顺德做pc端网站大数据精准营销获客
  • 中国站长站最好看免费观看高清视频了
  • 个人如何做短视频网站深圳百度国际大厦
  • 网页设计师是什么如何进行seo搜索引擎优化
  • 做网站需要用到的语言最佳bt磁力搜索引擎
  • 什么网站做推广磁力搜索引擎下载
  • 做网站制作的摘要郑州seo外包顾问
  • 东莞网站制作及推广价格网络营销的方式有哪些
  • 兰州医院网站制作怎么样关键词优化
  • 纯html css做的网站丁的老头seo博客
  • 国有林场网站建设免费建自己的网址
  • 网站排版代码怎么推广引流客户
  • 推广型网站制作公司百度推广客服
  • 品牌产品网站怎么做免费平台
  • 网站中的滑动栏怎么做如何做好网络营销?
  • 做企业网站收费多少网站推广平台有哪些
  • 深圳品牌模板网站建设免费友情链接网
  • 疫情防控和经济社会发展的关系seo优化sem推广
  • 做外包网站的公司是怎样的成都seo专家
  • 网站设计与建设考试沧州网站建设推广
  • 重庆的网络优化公司sem和seo是什么
  • 邯郸网站建设选哪家新人学会seo
  • 免费网站安全网站推广公司排名
  • 如何分析一个网站百度app下载安装 官方
  • 怎么建设网站大数据培训班出来能就业吗
  • wordpress4.9标签404郑州网站建设推广优化
  • 做网站的会计分录平台接广告在哪里接的
  • 苏州自助建站平台怎么在线上推广自己的产品
  • 网络规划设计师考试时间2022官网优化哪家专业
  • 深圳网站制作的公司济南seo网站排名优化工具