C++11中std::bind的使用
std::bind函数是用来绑定函数调用的某些参数的。std::bind它可以预先把指定可调用实体的某些参数绑定到已有的变量,产生一个新的可调用实体。它绑定的参数的个数不受限制,绑定的具体哪些参数也不受限制,由用户指定。
std::bind:(1)、将函数、成员函数和闭包转成function函数对象;(2)、将多元(n>1)函数转成一元函数或者(n-1)元函数。
std::bind本身是一种延迟计算的思想,它本身可以绑定普通函数、全局函数、静态函数、类静态函数甚至是类成员函数。无法使用std::bind绑定一个重载函数的参数,必须显式地指出需要绑定的重载函数的版本。成员函数区别于普通函数的一个特殊之处在于,其第一个参数必须是该类型的一个对象(或对象的指针或引用)。
std::bind接受一个函数(或者函数对象,或者任何你可以通过"(…)"符号调用的事物),生成一个其有某一个或多个函数参数被”绑定”或重新组织的函数对象。绑定的参数将会以值传递的方式传递给具体函数,占位符将会以引用传递。
std::bind需要注意事项:
(1)、bind预先绑定的参数需要传具体的变量或值进去,对于预先绑定的参数,是pass-by-value的;
(2)、对于不事先绑定的参数,需要传std::placeholders进去,从_1开始,依次递增。placeholder是pass-by-reference的;
(3)、bind的返回值是可调用实体,可以直接赋给std::function对象;
(4)、对于绑定的指针、引用类型的参数,使用者需要保证在可调用实体调用之前,这些参数是可用的;
(5)、类的this可以通过对象或者指针来绑定。
std::bind: Each argument may either be bound to a value or be a placeholder:
(1)、If bound to a value, calling the returned function object will always use that value as argument;
(2)、If a placeholder, calling the returned function object forwards an argument passed to the call (the one whose order number is specified by the placeholder).
std::bind receives a pointer to a function (it also can be a lambda expression or a functor) and receives a list of parameters that pass it to the function. As result, bind returns a new function object with a different prototype because all the parameters of the function were already specified.
A placeholder is an object that specifies the number of parameter in the bound function that will be used to enter this parameter.
std::bind is a Standard Function Objects that acts as a Functional Adaptor i.e. it takes a function as input and returns a new function Object as an output with with one or more of the arguments of passed function bound or rearranged.
下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:
#include "bind.hpp"
#include <iostream>
#include <string>
#include <functional> // std::bind
#include <random>
#include <memory>
#include <algorithm>//
// reference: http://en.cppreference.com/w/cpp/utility/functional/bind
static void f(int n1, int n2, int n3, const int& n4, int n5)
{std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}static int g(int n1)
{return n1;
}struct Foo_bind {void print_sum(int n1, int n2){std::cout << n1 + n2 << '\n';}int data = 10;
};int test_bind1()
{using namespace std::placeholders; // for _1, _2, _3...// demonstrates argument reordering and pass-by-referenceint n = 7;// (_1 and _2 are from std::placeholders, and represent future// arguments that will be passed to f1)auto f1 = std::bind(f, _2, _1, 42, std::cref(n), n);n = 10;f1(1, 2, 1001); // 1 is bound by _1, 2 is bound by _2, 1001 is unused// makes a call to f(2, 1, 42, n, 7)// nested bind subexpressions share the placeholdersauto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);f2(10, 11, 12);// common use case: binding a RNG with a distributionstd::default_random_engine e;std::uniform_int_distribution<> d(0, 10);std::function<int()> rnd = std::bind(d, e); // a copy of e is stored in rndfor (int n = 0; n<10; ++n)std::cout << rnd() << ' ';std::cout << '\n';// bind to a pointer to member functionFoo_bind foo;auto f3 = std::bind(&Foo_bind::print_sum, &foo, 95, _1);f3(5);// bind to a pointer to data memberauto f4 = std::bind(&Foo_bind::data, _1);std::cout << f4(foo) << '\n';// smart pointers can be used to call members of the referenced objects, too//std::cout << f4(std::make_shared<Foo_bind>(foo)) << '\n'// << f4(std::make_unique<Foo_bind>(foo)) << '\n';return 0;
}///
// reference: http://www.cplusplus.com/reference/functional/bind/
// a function: (also works with function object: std::divides<double> my_divide;)
double my_divide(double x, double y) { return x / y; }struct MyPair {double a, b;double multiply() { return a*b; }
};int test_bind2()
{using namespace std::placeholders; // adds visibility of _1, _2, _3,...// binding functions:auto fn_five = std::bind(my_divide, 10, 2); // returns 10/2std::cout << fn_five() << '\n'; // 5auto fn_half = std::bind(my_divide, _1, 2); // returns x/2std::cout << fn_half(10) << '\n'; // 5auto fn_invert = std::bind(my_divide, _2, _1); // returns y/xstd::cout << fn_invert(10, 2) << '\n'; // 0.2auto fn_rounding = std::bind<int>(my_divide, _1, _2); // returns int(x/y)std::cout << fn_rounding(10, 3) << '\n'; // 3MyPair ten_two{ 10, 2 };// binding members:auto bound_member_fn = std::bind(&MyPair::multiply, _1); // returns x.multiply()std::cout << bound_member_fn(ten_two) << '\n'; // 20auto bound_member_data = std::bind(&MyPair::a, ten_two); // returns ten_two.astd::cout << bound_member_data() << '\n'; // 10return 0;
}/
// reference: https://oopscenities.net/2012/02/24/c11-stdfunction-and-stdbind/
static void show(const std::string& a, const std::string& b, const std::string& c)
{std::cout << a << "; " << b << "; " << c << std::endl;
}int test_bind3()
{using namespace std::placeholders;// Thanks to the placeholders, you can change the order of the arguments passed as parameters to a bound function.auto x = bind(show, _1, _2, _3);auto y = bind(show, _3, _1, _2);auto z = bind(show, "hello", _2, _1);x("one", "two", "three");y("one", "two", "three");z("one", "two");return 0;
}/
// reference: http://stackoverflow.com/questions/22422147/why-is-stdbind-not-working-without-placeholders-in-this-example-member-functi
static void f_(int a, int b, int c)
{fprintf(stdout, "a = %d, b = %d, c = %d\n", a, b, c);
}struct foo_bind
{void f() const { fprintf(stdout, "foo_bind\n"); };
};int test_bind4()
{using namespace std::placeholders;// The first parameter of std::bind() is the function to be called, and the rest are the arguments of the call.std::function<void()> f_call = std::bind(f_, 1, 2, 3);f_call(); //Equivalent to f_(1,2,3)// If you need to specify that some parameters have to be specified at the call point,// you have to use placeholders to represent that parametersstd::function<void(int, int, int)> f_call2 = std::bind(f_, _1, _2, _3);f_call2(1, 2, 3); //Same as f_(1,2,3)// Note that the numbers of the placeholders specify the number of the parameter at the call point.// The first parameter of the call point is identified by _1, the second by _2, and so on.// This could be used to specify parameters in different ways, reordering the parameters of a function call, etc.std::function<void(int, int)> f_call3 = std::bind(f_, _1, 2, _2);f_call3(1, 3); //Equivalent to f_( 1 , 2 , 3 );std::function<void(int, int, int)> reordered_call = std::bind(f_, _3, _2, _1);reordered_call(3, 2, 1); //Same as f_( 1 , 2 , 3 );// std::bind() could be used to bind a member function to the object used to call itfoo_bind myfoo;std::function<void()> f = std::bind(&foo_bind::f, std::cref(myfoo));f();return 0;
}/
// reference: https://msdn.microsoft.com/en-us/library/bb982702.aspx
static void square(double x)
{std::cout << x << "^2 == " << x * x << std::endl;
}static void product(double x, double y)
{std::cout << x << "*" << y << " == " << x * y << std::endl;
}int test_bind5()
{using namespace std::placeholders;double arg[] = { 1, 2, 3 };std::for_each(&arg[0], arg + 3, square);std::cout << std::endl;std::for_each(&arg[0], arg + 3, std::bind(product, _1, 2));std::cout << std::endl;std::for_each(&arg[0], arg + 3, std::bind(square, _1));return (0);
}
GitHub:https://github.com/fengbingchun/Messy_Test
相关文章:

在图数据上做机器学习,应该从哪个点切入?
作者 | David Mack编译 | ronghuaiyang来源 | AI公园(ID:AI_Paradise)【导读】很多公司和机构都在使用图数据,想在图上做机器学习但不知从哪里开始做,希望这篇文章给大家一点启发。自从我们在伦敦互联数据中心(Connected Data Lon…

C++11中Lambda表达式的使用
Lambda表达式语法:[capture ] ( params ) mutable exception attribute -> return-type { body } 其中capture为定义外部变量是否可见(捕获),若为空,则表示不捕获所有外部变量,即所有外部变量均不可访问, 表示所有…

倒计时2天 | 专属技术人的盛会,为你而来!
5G 元年,人工智能 60 年,全球AI市场正发生着巨大的变化,顶尖科技企业和创新力量不断地进行着技术的更迭和应用的推进,专属于 AI 开发者的技术盛宴——2019 AI开发者大会(AI ProCon)将于 2 天后(…

了解大数据的特点、来源与数据呈现方式
作业来源:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2639 浏览2019春节各种大数据分析报告,例如: 这世间,再无第二个国家有能力承载如此庞大的人流量。http://www.sohu.com/a/290025769_313993春节人口迁徙大数据…

Mysql使用大全 从基础到存储过程
平常习惯了phpmyadmin等其他工具的的朋友有的根本就不会命令,如果让你笔试去面试我看你怎么办,所以,学习一下还是非常有用的,也可以知道你通过GUI工具的时候工具到底做了什么。Mysql用处很广,是php最佳拍档,…
GDAL库简介以及在Windows下编译过程
GDAL(Geospatial Data Abstraction Library,地理空间数据抽象库)是一个在X/MIT许可协议下的开源栅格空间数据转换库。官网http://www.gdal.org/index.html,也可参考GitHub https://github.com/OSGeo/gdal,最新release版本为2.1.1. GDAL是一个…

Hexo博客NexT主题美化之评论系统
前言 更多效果展示,请访问我的 个人博客。 效果图: Valine 诞生于2017年8月7日,是一款基于Leancloud的快速、简洁且高效的无后端评论系统。 教程: 登录 Leancloud 官网,注册之后创建一个应用,选择【设置】-…

倒计时1天 | 专属技术人的盛会,为你而来!
5G 元年,人工智能 60 年,全球AI市场正发生着巨大的变化,顶尖科技企业和创新力量不断地进行着技术的更迭和应用的推进,专属于 AI 开发者的技术盛宴——2019 AI开发者大会(AI ProCon)将于 明天(9 …

Selenium 2 WebDriver 多线程 并发
我用的是Selenium2,至于它的背景和历史就不赘述了。Selenium2也叫WebDriver。下面讲个例子,用WebDriverjava来写个自动化测试的程序。(如果能用firefox去测试的话,我就直接用Selenium IDE录脚本了。。。)有个前提&…
GDAL2.1.1库在Ubuntu14.04下编译时遇到的问题处理方法
不用作任何调整,直接在Linux下编译GDAL2.1.1源码的步骤是:$ ./configure $ make $ make install非常简单, 这样也能正常生成gdal动态库、静态库,如果想将生成的文件放到指定的目录,则需改第一条命令为:$ ./…

刷爆了!这项技术BAT力捧!程序员:我彻底慌了...
人工智能离我们还遥远吗?近日,海底捞斥资1.5亿打造了中国首家火锅无人餐厅;阿里酝酿了两年之久的全球首家无人酒店也正式开始运营,百度无人车彻底量产。李彦宏称,这是中国第一款能够量产的无人驾驶乘用车。而阿里的这家…
redux的compose源码,中文注释
用图片会更清楚一点,注释和代码会分的清楚源码解析参考请参考https://segmentfault.com/a/11...

做好职业规划:做自己的船长
要想在职场上有所斩获,就必须做好职业规划。对于职场中人来说,职业规划是职业发展中最关键的向导。职业规划因人而异,不同的对象有不同的需求,因此制定的目标与计划也不尽相同,但个人为自己做职业规划的方法和流程是大…

GDAL中GDALDataset::RasterIO分块读取的实现
GDALDataset类中的RasterIO函数能够对图像任意指定区域、任意波段的数据按指定数据类型、指定排列方式读入内存和写入文件中,因此可以实现对大影像的分块读、写运算操作。针对特大的影像图像,有时为了减少内存消耗,对图像进行分块读取很有必要…

掌握深度学习,为什么要用PyTorch、TensorFlow框架?
作者 | Martin Heller译者 | 弯月责编 | 屠敏来源 | CSDN(ID:CSDNnews)【导读】如果你需要深度学习模型,那么 PyTorch 和 TensorFlow 都是不错的选择。并非每个回归或分类问题都需要通过深度学习来解决。甚至可以说,并…

ICANN敦促业界使用DNSSEC,应对DNS劫持攻击
HTTPS加密 可以有效帮助服务器应对DNS欺骗、DNS劫持、ARP攻击等安全威胁。DNS是什么?DNS如何被利用?HTTPS如何防止DNS欺骗? DNS如何工作? 如果您想访问www.example.com,您的浏览器需要找到该特定Web服务器的IP地址。它…

Lucene.net: the main concepts
2019独角兽企业重金招聘Python工程师标准>>> In the previous post you learnt how to get a copy of Lucene.net and where to go in order to look for more information. As you noticed the documentation is far from being complete and easy to read. So in …

einsum,一个函数走天下
作者 | 永远在你身后转载自知乎【导读】einsum 全称 Einstein summation convention(爱因斯坦求和约定),又称为爱因斯坦标记法,是爱因斯坦 1916 年提出的一种标记约定,本文主要介绍了einsum 的应用。简单的说ÿ…
常用排序算法的C++实现
排序是将一组”无序”的记录序列调整为”有序”的记录序列。假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,rirj,且ri在rj之前࿰…

4.65FTP服务4.66测试登录FTP
2019独角兽企业重金招聘Python工程师标准>>> FTP服务 测试登录FTP 4.65FTP服务 文件传输协议(FTP),可以上传和下载文件。比如我们可以把Windows上的文件shan上传到Linux,也可以把Linux上的文件下载到Windows上。 Cent…

JavaScript的应用
DOM, BOM, XMLHttpRequest, Framework, Tool (Functionality) Performance (Caching, Combine, Minify, JSLint) ---------------- 人工做不了,交给程序去做,这样可以流程化。 Maintainability (Pattern) http://www.jmarshall.com/easy/http/ http://dj…

miniz库简介及使用
miniz:Google开源库,它是单一的C源文件,紧缩/膨胀压缩库,使用zlib兼容API,ZIP归档读写,PNG写方式。关于miniz的更详细介绍可以参考:https://code.google.com/archive/p/miniz/miniz.c is a loss…

iOS之runtime详解api(三)
第一篇我们讲了关于Class和Category的api,第二篇讲了关于Method的api,这一篇来讲关于Ivar和Property。 4.objc_ivar or Ivar 首先,我们还是先找到能打印出Ivar信息的函数: const char * _Nullable ivar_getName(Ivar _Nonnull v) …

亚马逊首席科学家李沐「实训营」国内独家直播,马上报名 !
开学了,别人家的学校都开始人工智能专业的学习之旅了,你呢?近年来,国内外顶尖科技企业的 AI 人才抢夺战愈演愈烈。华为开出200万年薪吸引 AI 人才,今年又有 35 所高校新增人工智能本科专业,众多新生即将开展…
人脸检测库libfacedetection介绍
libfacedetection是于仕琪老师放到GitHub上的二进制库,没有源码,它的License是MIT,可以商用。目前只提供了windows 32和64位的release动态库,主页为https://github.com/ShiqiYu/libfacedetection,采用的算法好像是Mult…

倒计时1天 | 2019 AI ProCon报名通道即将关闭(附参会指南)
2019年9月5-7日,面向AI技术人的年度盛会—— 2019 AI开发者大会 AI ProCon,震撼来袭!2018 年由 CSDN 成功举办 AI 开发者大会一年之后,全球 AI 市场正发生着巨大的变化。顶尖科技企业和创新力量不断地进行着技术的更迭和应用的推…

法院判决:优步无罪,无人车安全员可能面临过失杀人控诉
据路透社报道,负责优步无人车在亚利桑那州致人死亡事件调查的律师事务所发布公开信宣布,优步在事故中“不承担刑事责任”,但是当时在车上的安全员Rafaela Vasquez要接受进一步调查,可能面临车辆过失杀人罪指控。2018年3月…

09 Storage Structure and Relationships
目标:存储结构:Segments分类:Extents介绍:Blocks介绍:转载于:https://blog.51cto.com/eread/1333894

边界框的回归策略搞不懂?算法太多分不清?看这篇就够了
作者 | fivetrees来源 | https://zhuanlan.zhihu.com/p/76477248本文已由作者授权,未经允许,不得二次转载【导读】目标检测包括目标分类和目标定位 2 个任务,目标定位一般是用一个矩形的边界框来框出物体所在的位置,关于边界框的回…