c++11 特性 std::function 与 std::bind
来源:互联网 发布:矩阵分解优化问题 编辑:程序博客网 时间:2024/05/17 23:39
~~~~我的生活,我的点点滴滴!!
std::function 和 std::bind
标准库函数bind()和function()定义于头文件<functional>中(该头文件还包括许多其他函数对象),用于处理函数及函数参数。类模版 std::function 是一种通用、多态的函数封装。
function
std::function 的实例可以对任何可以调用的 目标 进行存储、复制、和调用操作,这些目标包括函数、lambda 表达式、绑定表达式、以及其它函数对象等。
看下面的例子:
#include <functional>#include <iostream> struct Foo { Foo(int num) : num_(num) {} void print_add(int i) const { std::cout << num_+i << '\n'; } int num_;}; void print_num(int i){ std::cout << i << '\n';} int main(){ // 保存自由函数 std::function<void(int)> f_display = print_num; f_display(-9); // 保存 lambda 表达式 std::function<void()> f_display_42 = []() { print_num(42); }; f_display_42(); // 保存 std::bind 的结果 std::function<void()> f_display_31337 = std::bind(print_num, 31337); f_display_31337(); // 保存成员函数 std::function<void(const Foo&, int)> f_add_display = &Foo::print_add; Foo foo(314159); f_add_display(foo, 1);}
输出:
-9
42
31337
314160
bind
bind()接受一个函数(或者函数对象,或者任何你可以通过”(…)”符号调用的事物),生成一个其有某一个或多个函数参数被“绑定”,
要绑定的参数被复制或移动的,并且永远不会通过引用传递,除非包裹在std::ref或std::cref重复在相同的绑定表达式的占位符(多_1的例子)是允许的,
但结果却只有明确定义,如果相应的参数(u1)是一个左值或不可移动的右值。
#include <random>#include <iostream>#include <functional> void f(int n1, int n2, int n3, const int& n4, int n5){ std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';} int g(int n1){ return n1;} struct Foo { void print_sum(int n1, int n2) { std::cout << n1+n2 << '\n'; } int data = 10;}; int main(){ using namespace std::placeholders; // 传值用引用方式 std::cref(n) int n = 7; auto f1 = std::bind(f, _2, _1, 42, std::cref(n), n); n = 10;// 1 被绑定为_1, 2 被绑定为_2, 1001没用 f1(1, 2, 1001); // 潜入表达式,可以共享占用符 auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5); f2(10, 11, 12); // 绑定到普通成员函数 Foo foo; auto f3 = std::bind(&Foo::print_sum, foo, 95, _1); f3(5); // 绑定到普通成员变量 auto f4 = std::bind(&Foo::data, _1); std::cout << f4(foo) << '\n';}
输出:
2 1 42 10 7
12 12 12 4 5
100
10
注:
std::ref()表示传引用
std::cref()表示传不变引用
特别注意:
bind对于不事先绑定的参数,通过std::placeholders传递的参数是通过引用传递的
bind对于预先绑定的函数参数是通过值传递的
看下面一段代码就知道了
#include <iostream>using namespace std;class A{public: void fun_3(int k,int m) { cout<<k<<" "<<m<<endl; }}; void fun(int x,int y,int z){ cout<<x<<" "<<y<<" "<<z<<endl;} void fun_2(int &a,int &b){ a++; b++; cout<<a<<" "<<b<<endl;} int main(int argc, const char * argv[]){ auto f1 = bind(fun,1,2,3); //表示绑定函数 fun 的第一,二,三个参数值为: 1 2 3 f1(); //print:1 2 3 auto f2 = bind(fun, placeholders::_1,placeholders::_2,3); //表示绑定函数 fun 的第三个参数为 3,而fun 的第一,二个参数分别有调用 f2 的第一,二个参数指定 f2(1,2);//print:1 2 3 auto f3 = bind(fun,placeholders::_2,placeholders::_1,3); //表示绑定函数 fun 的第三个参数为 3,而fun 的第一,二个参数分别有调用 f3 的第二,一个参数指定 //注意: f2 和 f3 的区别。 f3(1,2);//print:2 1 3 int n = 2; int m = 3; auto f4 = bind(fun_2, n,placeholders::_1); f4(m); //print:3 4 cout<<m<<endl;//print:4 说明:bind对于不事先绑定的参数,通过std::placeholders传递的参数是通过引用传递的 cout<<n<<endl;//print:2 说明:bind对于预先绑定的函数参数是通过值传递的 A a; auto f5 = bind(&A::fun_3, a,placeholders::_1,placeholders::_2); f5(10,20);//print:10 20 std::function<void(int,int)> fc = std::bind(&A::fun_3, a,std::placeholders::_1,std::placeholders::_2); fc(10,20);//print:10 20 return 0;}
看一段代码:
#include <functional>#include <iostream> void f(int& n1, int& n2, const int& n3){ std::cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << '\n'; ++n1; // increments the copy of n1 stored in the function object ++n2; // increments the main()'s n2 // ++n3; // compile error} int main(){ int n1 = 1, n2 = 2, n3 = 3; std::function<void()> bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3)); n1 = 10; n2 = 11; n3 = 12; std::cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << '\n'; bound_f(); std::cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';}
输出:
Before function: 10 11 12In function: 1 11 12After function: 10 12 12从上面看出,其实绑定时,按值已经传递好了,是不会在更改的,但是如果使用了ref与cref,他们按地址传递,就能更改其值。
参照 c++ 官网 http://zh.cppreference.com/w/cpp/utility/functional/
如果 在最后面加上 function (http://zh.cppreference.com/w/cpp/utility/functional/function)他就会跳转到function说明
如果 加上bind 就会跳转到bind说明。
- c++11 特性 std::function 与 std::bind
- C++11新特性之std::bind与std::function
- C++11 std::bind与std::function
- c++11 std::bind与std::function
- std::bind与std::function
- C++11新特性之std::function & std::bind
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- c++11特性与cocos2d-x 3.0之std::bind与std::function
- std::function std::bind
- std::function std::bind
- c++11 对std::function与std::bind理解
- std::function与std::bind 函数指针
- 在CentOS安装CMake
- 【Leetcode长征系列】Climbing Stairs
- ACdream 1099 瑶瑶的第K大
- UVA10790 How Many Points of Intersection?
- 儿童迎合热让他共和党管
- c++11 特性 std::function 与 std::bind
- 初学OAF的问题
- CSS实现背景透明,文字不透明(各浏览器兼容)
- 数字图像处理-频域增强
- BaseDao
- 使用内部(com.android.internal)和隐藏(@hide)API[第2部分,定制android.jar]
- 富豪们掌握着获得智慧的智慧
- poj 1308 Is It A Tree?
- 导入源码步骤