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

中国建信网官方网站做类似淘宝网站怎么做

中国建信网官方网站,做类似淘宝网站怎么做,百度搜索关键词,成都网站建设学习c11之前#xff0c;STL中提供了bind1st以及bind2nd绑定器 首先来看一下他们如何使用#xff1a; 如果我们要对vector中的元素排序#xff0c;首先会想到sort#xff0c;比如#xff1a; void output(const vectorint vec) {for (auto v : vec) {cout 11之前STL中提供了bind1st以及bind2nd绑定器 首先来看一下他们如何使用 如果我们要对vector中的元素排序首先会想到sort比如 void output(const vectorint vec) {for (auto v : vec) {cout v ;}cout endl; }int main() {vectorint 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(), greaterint());output(vec);//less 从小到大排序sort(vec.begin(), vec.end(), lessint());output(vec);return; }sort最后一个参数传入的greater或less都被称为函数对象顾名思义表现像函数的对象因为他们的调用都是在后面加上()。 其实这是因为他们都重载了operator()。 来看下greater的定义 templateclass _Ty voidstruct 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(greaterint(), 70));if (it1 ! vec.end()) {vec.insert(it1, 70);}这里使用bind1st(greaterint(), 70)作为find_if的第三个参数bind1st的作用首先将70绑定到二元函数对象greater的第一个参数上其次将二元函数对象greater转为一元函数对象因为70已知了传入到find_if的第三个参数中。这便是他的应用场景或者还可以使用bind2nd和less的搭配 auto it1 find_if(vec.begin(), vec.end(),bind2nd(lessint(), 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() {functionvoid() func1 hello1;//functionvoid() func1(hello1);func1();//func1.operator() hello1();functionvoid(string) func2 hello2;func2(gao);//func2.operator()(string str) hello2(str);functionint(int, int) func3 [](int a, int b) - int { return a b; };cout func3(100, 200) endl;//通过function调用类的成员方法functionvoid(Test*, string) func5 Test::hello;func5(Test(), call Test::hello!);return 0; }对function的调用实际上是调用了function的()重载从而调用原函数。上面的例子中可以看到lambda表达式也可以通过function调用。这其实就说明了function的真正用途保存函数对象的类型也是对函数对象的封装。这也是它和c语言的函数指针的区别lambda无法通过函数指针调用。 现在有这样一个场景 两多个函数有大部分的代码都是一样的其中只有一两行代码有不一样的地方我们可以对这个不一样的地方使用function做一个抽象比如 有两个vector打印函数一个打印模50的元素一个打印大于10的元素 void print(vectorint number, functionbool(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(vectorint number, functionvoid () 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;}; }这里我们通过functionvoid () printer传递出这个闭包。 然后在需要的地方这样即可 functionvoid() printer; getMinMax(numbers, printer); ......printer();这里的printer其实是我们前面从getMinMax函数出传出的闭包这个闭包捕获了min和max。我们直接传递这个闭包给需要的地方使用而不用传递裸的两个数值是不是优雅的不少 bind /* c11 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就复用起来了functionvoid(string) func1 bind(hello, placeholders::_1);func1(hello gao);return 0; }使用bind和function的线程池例子 class Thread { public://接收一个函数对象参数都绑定了所以不需要参数Thread(functionvoid() func) : _func(func) {}thread start(){thread t(_func);return t;} private:functionvoid() _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:vectorThread* _pool;vectorthread _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;};*///以值传递ab,lambda实现的重载函数operator()中是const方法不能修改成员变量//如果一定要修改将lambda修饰成mutable但是这并不会改变a的值因为这是值传递//int a 10;//int b 20;//auto func3 [a, b]() /*mutable*///{// int tmp a;// a b;// b tmp;//};vectorint 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() {mapint, functionint(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_ptrFILE, functionvoid(FILE*)ptr1(fopen(data.txt, w), [](FILE *pf) { fclose(pf); });//优先队列using FUNC functionbool(Data, Data);priority_queueData, vectorData, FUNCmaxHeap([](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://www.pierceye.com/news/235164/

相关文章:

  • 综合电子商务型企业网站怎么做网站的网盘
  • ucenter使用自己做的网站房地产新闻时事热点
  • 企业网站备案 过户电商运营视频教程
  • 做网站运营这工作怎么样北京网站优化价格
  • 河南专业网站建设网站怎么做高权重
  • 国内大型电子网站建设做网站时怎么透明化
  • 微应用和微网站的区别手机网站开发的目的
  • 网站ico开一个网站建设公司好
  • wordpress中文站cn外贸网站怎么换域名
  • 淘宝客怎么做直播网站吗学校网站建设发展概况分析
  • 广州网站外贸推广建筑师必看的16部纪录片
  • 深圳网站建设平台网站右侧浮动广告
  • 中英文网站源码浙江东南网架公司
  • 个人备案网站放什么资料培训
  • html做企业门户网站提供设计的网站
  • 成都三合一网站建设成年s8视频加密线路
  • 做网站购买服务器如何优化网络
  • 企业公司网站 北京怎样用前端知识制作企业网站
  • 精湛的赣州网站建设襄阳哪里有做网站的
  • 拿了网赌代理后怎样做自己的网站河南最新消息今天
  • 北京最大的网站开发公司中山市企业网站seo营销工具
  • 苏州营销型网站建设方案哪些网站做的比较好的
  • 淘宝上买的建设网站能退款吗app怎么查网站备案
  • 电子商务网站开发与设计报告专业网站建设公司兴田德润怎么样
  • 如何建立p2p网站win2003怎么做网站
  • 免费网页设计制作网站建筑公司愿景口号大全
  • 个人可以做网站维护吗专业团队电脑壁纸
  • 东营专业网站建设公司排行鞍山市人力资源招聘信息网
  • 郑州网站建设蝶动小公司使用的网站开发
  • 合肥网站seo技术软件开发工程师简历模板