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

C++11中std::bind的使用相关推荐

  1. C++/C++11中std::string用法汇总

    C++/C++11中std::string是个模板类,它是一个标准库.使用string类型必须首先包含<string>头文件.作为标准库的一部分,string定义在命名空间std中. st ...

  2. C++11中std::packaged_task的使用

    C++11中的std::packaged_task是个模板类.std::packaged_task包装任何可调用目标(函数.lambda表达式.bind表达式.函数对象)以便它可以被异步调用.它的返回 ...

  3. C++11中std::function的使用

    类模版std::function是一种通用.多态的函数封装.std::function的实例可以对任何可以调用的目标实体进行存储.复制.和调用操作,这些目标实体包括普通函数.Lambda表达式.函数指 ...

  4. C语言中task的用法,C++11中std::packaged_task的使用详解

    C++11中的std::packaged_task是个模板类.std::packaged_task包装任何可调用目标(函数.lambda表达式.bind表达式.函数对象)以便它可以被异步调用.它的返回 ...

  5. C++11中std::async的使用

    C++11中的std::async是个模板函数.std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待Fn执行完成就可返回,返回结果是个std::future对 ...

  6. C++11中std::shared_future的使用

    C++11中的std::shared_future是个模板类.与std::future类似,std::shared_future提供了一种访问异步操作结果的机制:不同于std::future,std: ...

  7. C++11中std::future的使用

    C++11中的std::future是一个模板类.std::future提供了一种用于访问异步操作结果的机制.std::future所引用的共享状态不能与任何其它异步返回的对象共享(与std::sha ...

  8. 概率论中指数分布介绍及C++11中std::exponential_distribution的使用

    指数分布:在深度学习中,我们经常会需要一个在x=0点处取得边界点(sharp point)的分布.为了实现这一目的,我们可以使用指数分布(exponential distribution): p(x; ...

  9. 概率论中高斯分布(正态分布)介绍及C++11中std::normal_distribution的使用

    高斯分布:最常用的分布是正态分布(normal distribution),也称为高斯分布(Gaussian distribution): 正态分布N(x;μ,σ2)呈现经典的"钟形曲线&q ...

最新文章

  1. 5G 标准 — R15
  2. 基于python的数据挖掘网课-利用 Python 练习数据挖掘
  3. 如何生成项目的chm文档
  4. The mook jong 计数DP
  5. rails table html,Ruby on Rails:如何将字符串呈现为HTML?
  6. 数字图像处理(五)——形态学
  7. PyQT项目优化---添加多线程数控制
  8. 实现List按与一个字符串的相似度和字母顺序排序(适用于模糊查询后的排序)...
  9. fn:startsWith()函数
  10. 空间目录Tomcat ShutDown出现 Insufficient space for shared memory file:
  11. 提交百度快速收录真的能达到秒收录吗
  12. 你可知用FlexGrid做开发,轻松处理百万级表格数据
  13. 数据库学习之num1
  14. 提升机器算法LightGBM(图解+理论+增量训练python代码+lightGBM调参方法)
  15. 微信公众号网页授权登录完整步骤版学不会你打我....
  16. java基础入门篇1
  17. Letax 空格、字号、括号、序号
  18. kinect体感互动解决方案:体感炫舞
  19. ADC的基本工作原理
  20. 面试官:CPU 是如何工作的?我一脸懵逼。。

热门文章

  1. db2 linux 导入数据_「软件资料」-「软件使用」-Linux 导入、导出 MySQL 数据库命令...
  2. request中的内容存储_宜信开源|调用链系列(3):解读UAVStack中的调用链技术...
  3. 将图片(路径)转换为Base64 和 将base64转换为file类型
  4. 实验三 Gmapping建图
  5. 利用urllib2实现http post请求源码示例
  6. 在Ubuntu 14.04 64bit上安装redis 3.0.3
  7. 在ubuntu 14.04 64bit上安装酷我音乐盒Linux客户端kwplayer
  8. 交互两个数(不引入第三个变量)
  9. Python入门基础教程 Working with Python – Introductory Level
  10. XFS 文件系统 (一) :设计概览