c++的function是一种函数包装器,可以保存其他可调用对象,如函数,lambada表达式,bind()表达式,成员函数等。bind可以生成函数的转发调用包装器。bind和function都定义在头文件<functional>
里。
参考链接
- cpp reference std::function
- cpp reference std::bind
使用std::function绑定一个自由函数
#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersvoid printValues(int a, int b, int c) {std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}int main() {//绑定一个function对象到自由函数,function传入的函数返回值和参数列表需要和实际绑定的函数一样std::function<void(int,int,int)> func = printValues;func(100, 200, 300);return 0;
}
使用std::function绑定一个lambda表达式
#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersint main() {//绑定一个lambda表达式std::function<void(int,int)> funcL = [](int a,int b) -> void{std::cout << "a = " << a << " b = " << b << std::endl;};funcL(123, 456);return 0;
}
使用std::function绑定一个类成员函数,推荐使用std::bind来绑定类的成员函数
#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersstruct MyFoo
{int val;MyFoo(int i) : val(i) { std::cout << "MyFoo cons" << i << '\n'; }void printVal() const { std::cout << val << '\n'; }void printAddVal(int i) { std::cout << val + i << '\n'; }
};int main() {// 存储到成员函数的调用//因为成员函数在调用时,会隐式传入this指针,所以绑定时,需要传入一个MyFoo&参数//如果成员函数用const修饰,那么要传入const MyFoo&std::function<void(const MyFoo&)> my_foo_print = &MyFoo::printVal;MyFoo mfoo(27895);my_foo_print(mfoo);my_foo_print(30001122); //30001122被构造成MyFoo的对象std::function<void(MyFoo&, int)> my_foo_printadd = &MyFoo::printAddVal; my_foo_printadd(mfoo,20);//my_foo_printadd(46123,20); //46123会被构造成为一个临时对象,临时对象不能绑定到const引用,编译会报错//使用std::bind来绑定,类的成员函数MyFoo mfoo2(54321);std::function<void(void)> my_foo_print2 = std::bind(&MyFoo::printVal, &mfoo2);my_foo_print2();std::function<void(int)> my_foo_printadd2 = std::bind(&MyFoo::printAddVal, &mfoo2, std::placeholders::_1);my_foo_printadd2(300);return 0;
}
使用std::bind,比较常用的就是绑定类成员函数或一个自由函数
#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersvoid printValues(int a, int b, int c) {std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}struct MyFoo
{int val;MyFoo(int i) : val(i) { std::cout << "MyFoo cons" << i << '\n'; }void printVal() const { std::cout << val << '\n'; }void printAddVal(int i) { std::cout << val + i << '\n'; }
};using namespace std::placeholders;int main()
{MyFoo foo(100);auto print = std::bind(&MyFoo::printVal, &foo);print();auto printAdd = std::bind(&MyFoo::printAddVal, &foo, _1);printAdd(200); //参数传入200,对应占位符_1auto printAdd2 = std::bind(&MyFoo::printAddVal, &foo, 50);printAdd2(); //参数固定传入50//传给printValues的第一个参数是display的第2个参数,30//printvalues的第二个参数是固定值20//printvalues的第3个参数是display的第1个参数,10auto display = std::bind(printValues, _2, 20, _1);display(10, 30); //a = 10, b = 20, c = 30//传给printValues的第一个参数是display2的第3个参数,20//printvalues的第二个参数是display2的第一个参数,30//printvalues的第3个参数是display的第2个参数,10auto display2 = std::bind(printValues, _3, _1, _2);display2(30, 10, 20); //a = 20, b = 30, c = 10return 0;
}
使用std::function定义一个函数类型,一般在给其他类提供一个callback类型时使用。
#include <iostream>
#include <functional> // 包含 std::bind 和 std::placeholdersvoid printValues(int a, int b, int c) {std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}typedef std::function<void(int,int,int)> ShowFunc;
using Display = std::function<void(int,int,int)>;using namespace std::placeholders;int main()
{ShowFunc func = printValues;func(100, 200, 300);Display disp = printValues;disp(400, 500, 600);return 0;
}