C++ | std::bind
文章目录
- C++ | std::bind
- std::bind函数原型
- bind函数参数
- 返回对象的类型:
- 实战
- 1.普通函数/类成员函数/类成员变量
- 2.模板函数
- 3.lambda表达式
- Reference
std::bind函数原型
// 无返回值(1)
template <class Fn, class... Args> /* unspecified */ bind (Fn&& fn, Args&&... args);
// 有返回值(2)
template <class Ret, class Fn, class... Args> /* unspecified */ bind (Fn&& fn, Args&&... args);
bind函数参数
fn 为绑定的函数对象,比如函数对象、函数指针、函数引用、成员函数或者数据成员函数。
args 为函数的入参列表,使用命名空间占位符std::placeholders::_1(第1个参数),std::placeholders::_2(第2个参数)等标志参数。
每个参数可以绑定到一个值或者是一个占位符:
- 如果绑定到一个值,调用返回的函数对象将始终使用该值作为参数。
- 如果是占位符,则调用返回的函数对象会将传递给调用的参数转发给调用(其顺序号由占位符指定的参数)。
调用返回的对象返回与 fn 相同的类型,除非将特定的返回类型指定为 Ret (2)(请注意,Ret 是唯一不能通过传递给此函数的参数隐式推导的模板参数)。
返回对象的类型:
返回一个函数对象,它的返回值与 fn 相同的结果,其参数也绑定到 args…(或转发,用于占位符)。
对如果f是指向类的成员函数,则返回函数第一个参数应该是该类的成员、或者成员对象的引用、或者是成员对象的指针。
实战
1.普通函数/类成员函数/类成员变量
#include <functional> // std::bind
#include <iostream> // std::cout
// a function: (also works with function object: std::divides<double>
// randy_divide;)
double randy_divide(double x, double y) { return x / y; }
struct RandyPair {
double randy, sesame;
double multiply() { return randy * sesame; }
static double Add(double lhs, double rhs) {
return lhs + rhs;
}
};
int main() {
using namespace std::placeholders; // adds visibility of _1, _2, _3,...
// binding functions:
auto fn_five = std::bind(randy_divide, 10, 2); // returns 10/2
std::cout << fn_five() << '\n'; // 5
auto fn_half = std::bind(randy_divide, _1, 2); // returns x/2
std::cout << fn_half(22) << '\n'; // 11
auto fn_invert = std::bind(randy_divide, _2, _1); // returns y/x
std::cout << fn_invert(10, 2) << '\n'; // 0.2
auto fn_rounding = std::bind<int>(randy_divide, _1, _2); // returns int(x/y)
std::cout << fn_rounding(9, 3) << '\n'; // 3
RandyPair three_eleven{3, 11};
// binding members:
auto bound_member_fn =
std::bind(&RandyPair::multiply, _1); // returns x.multiply()
std::cout << bound_member_fn(three_eleven) << '\n'; // 33
auto bound_member_data =
std::bind(&RandyPair::randy, three_eleven); // returns ten_two.a
std::cout << bound_member_data() << '\n'; // 3
// function pointer
RandyPair *pRandyPairPtr = new RandyPair();
pRandyPairPtr->randy = 3.0;
pRandyPairPtr->sesame = 8.0;
auto bindFuncPtr = std::bind(&RandyPair::multiply, pRandyPairPtr);
std::cout << "bindFuncPtr(): " << bindFuncPtr() << '\n';
auto bindClassStaticFunc = std::bind(&RandyPair::Add, _1, _2);
std::cout << "bindClassStaticFunc(2, 13): " << bindClassStaticFunc(2, 13) << '\n';
return 0;
}
结果:
5
11
0.2
3
33
3
bindFuncPtr(): 24
bindClassStaticFunc(2, 13): 15
2.模板函数
#include <functional> // std::bind
#include <iostream> // std::cout
template <class T>
void TemplateBindFunc(T lhs, T rhs)
{
std::cout << "模板函数被调用, lhs = " << lhs << ", rhs = " << rhs << std::endl;
}
int main() {
using namespace std::placeholders; // adds visibility of _1, _2, _3,...
auto templateFunc = std::bind(&TemplateBindFunc<int>, _1, _2);
templateFunc(2, 13);
return 0;
}
结果:
模板函数被调用, lhs = 2, rhs = 13
3.lambda表达式
#include <functional> // std::bind
#include <iostream> // std::cout
int main() {
auto lamdaFunc = std::bind(
[](int randy, int sesame "") {
std::cout << "lambda表达式, randy = " << randy << ", sesame = " << sesame << std::endl;
},
std::placeholders::_1, std::placeholders::_2);
lamdaFunc(1, 22);
return 0;
}
结果:
lambda表达式, randy = 1, sesame = 22
Reference
-
C++11 - std::bind简要介绍以及可绑定函数的几种形式总结
-
【C++11 新特性】bind(二)
欢迎关注公众号【三戒纪元】