2 预定义的Function object 和Binder
- 位于头文件
<functional>
1 预定义的function object
其中,bit_and,bit_or,bit_xor自c++11;
说明:
- 对对象排序或比较,(用于排序函数和关联容器)时,默认用
less<>
为比较准则,无序容器默认相等性准则eequal_to<>
2 Function Adapter 和Binder
- 函数适配器: 指将不同的函数对象结合起来的东西,自身也是一个函数对象
说明:
- 最重要的是:bind()
- 在已经有的函数对象之外另外配接即合成新的函数对象;
- 调用全局函数;
- 针对object,pointer toobject 和 smart pointer to object 调用成员函数;
2.1 bind() 适配器和调用全局函数
//simple(1)
template <class Fn, class... Args>
/* unspecified */ bind (Fn&& fn, Args&&... args);
//with return type (2)
template <class Ret, class Fn, class... Args>
/* unspecified */ bind (Fn&& fn, Args&&... args);
说明:
- bind()用来将参数绑定到可调用对象;
- 欲使用被传入的参数,利用预定义占位符
_1,_2,_3,...
,定义与std:ppaceholders
内;
例子:
using namespace std::placeholders; // adds visibility of _1, _2, _3,...
//---------------省略------------
double my_divide (double x, double y) {return x/y;}
// binding functions:绑定了两个参数
auto fn_five = std::bind (my_divide,10,2); // returns 10/2
std::cout << fn_five() << '\n';// 5
//绑定了一个传入参数为第一个参数
auto fn_half = std::bind (my_divide,_1,2); // returns x/2
std::cout << fn_half(10) << '\n'; // 5
//绑定传入的第一个参数为函数的参数二,传入的第二个参数为函数的参数一
auto fn_invert = std::bind (my_divide,_2,_1); // returns y/x
std::cout << fn_invert(10,2) << '\n'; // 0.2
//绑定传入的第一个参数为函数的参数1,传入的第二个参数为函数的参数2
auto fn_rounding = std::bind<int> (my_divide,_1,_2); // returns int(x/y)
std::cout << fn_rounding(10,3) << '\n'; // 3
2.2 调用成员函数和成员
struct MyPair {
double a,b;
double multiply(int n) {return a*b;}
};
//-------------省略----------
MyPair ten_two {10,2};
// binding members:
auto bound_member_fn = std::bind (&MyPair::multiply,_1,45); // returns x.multiply(45)
std::cout << bound_member_fn(ten_two) << '\n'; // 20
auto bound_member_data = std::bind (&MyPair::a,ten_two); // returns ten_two.a
std::cout << bound_member_data() << '\n';
说明:
std::bind (&MyPair::multiply,_1,45); // returns x.multiply(45)
由于bind()第一个实参是成员函数,第二个参数定义“调用成员函数”的对象,其他任何实参都会被传递给成员函数;则45就是成员函数的参数;std::bind (&MyPair::a,ten_two)
:绑定参数到对象的成员;
【注意】
mem_fn() 适配器
对于成员函数,可以使用mem_fn()适配器,就不需要用占位符来表示调用者;
struct MyPair {
double a,b;
double multiply() {return a*b;}
void print1() {cout<<"print1 !!"<<endl;}
void print2(string s) {cout<<"print1 2:"<<s<<endl;}
};
std::mem_fn(&MyPair::multiply);
//如果需要传递参数的话
std::mem_fn(&MyPair::print1)(n); //第一个实参作为对象,这里: n.print1()
std::mem_fn(&MyPair::print2)(n,"hello") // n.print2("hello")
not1 和not2 适配器:可视为过时
作用: 令预定义的函数对象意义相反;