摘自:深入应用C++11:代码优化与工程级应用
#1.5.1 可调用对象
在C++98/03中,可调用对象包括以下几种:
- 函数指针
- 具有opterator()成员函数的类对象(仿函数)
- 可被转换为函数指针的类对象
- 类成员(函数)指针
//仿函数
class Foo
{
public:
void operator()(void)
{
cout<<"operator()"<<endl;
}
};
Foo foo;
foo();
//可被转换为函数指针的类对象
class Bar
{
public:
static void func(void)
{
cout<<"func()"<<endl;
}
using fr_t=void (*) (void);
operator fr_t(void)
{
return func;
}
};
Bar bar;
bar();
//类成员(函数)指针
class Person
{
public:
int id=100;
void func(void)
{
cout<<"func()"<<endl;
}
};
void (Person::*func_ptr)(void)=&Person::func;//类成员函数指针
Person person;
(person.*func_ptr)();
int Person::*id_ptr=&Person::id;//类成员变量指针
cout<<person.*id_ptr<<endl;
在C++98/03中,保存或传递可调用对象的方法十分繁琐。
在C++11中,提供了std::function和std::bind统一了可调用对象的各种操作。
#1.5.2 可调用对象包装器–std::function
std::function是可调用对象的包装器。它是一个类模板可以容纳除类成员(函数)指针之外的所有可调用对象。
它的功能等同于函数指针,可以保存函数、函数对象、函数指针等。std::function主要应用在回调函数。
//绑定到函数
void func(void)
{
cout<<__FUNCTION__<<endl;
}
function<void(void)> func_ptr=func;
func_ptr();
//绑定到类静态成员函数
class Person
{
public:
static void Count(void)
{
cout<<"Count"<<endl;
}
};
function<void(void)> func_ptr=Person::Count;
func_ptr();
//绑定到仿函数
class Person
{
public:
void operator()(int id)
{
cout<<"Id:"<<id<<endl;
}
};
Person person;
function<void(int)> func_ptr=person;
func_ptr(123);
//绑定到可转换为函数指针的类对象
class Bar
{
public:
static void func(void)
{
cout<<"func()"<<endl;
}
using fr_t=void (*) (void);
operator fr_t(void)
{
return func;
}
};
Bar bar;
function<void(void)> func_ptr=bar;
func_ptr();
#1.5.3 std::bind绑定器
std::bind用来将可调用对象和其参数一起绑定。绑定后的结果可以使用std::function保存。如:
#include <stdlib.h>
#include <functional>
#include <iostream>
void output(int x, int y)
{
std::cout << x << " " << y << std::endl;
}
int main(void)
{
std::function<void(void)> func_ptr = std::bind(output, 1, 2);
func_ptr(); //输出:1 2
std::function<void(int)> func1_ptr = std::bind(output, std::placeholders::_1, 2);
func1_ptr(1); //输出:1 2
system("pause");
return 0;
}
std::bind可以直接绑定函数的所有参数,也可以仅绑定部分参数。在绑定部分参数的时候,通过使用std::placeholders来决定空位参数将会属于调用发生时的第几个参数。
std::bind的使用例子
- 使用bind简化和增强bind1st和bind2nd
如:查找小于5的元素的个数。
#include <stdlib.h>
#include <functional>
#include <vector>
#include <algorithm>
#include <iostream>
int main(void)
{
std::vector<int> vect = { 0,1,2,3,4,5,6,7,8,9 };
auto less_func = std::bind(std::less<int>(),std::placeholders::_1, 5);
int count = std::count_if(vect.begin(),vect.end(),less_func);
std::cout << count << std::endl;
system("pause");
return 0;
}
- 使用组合bind函数
bind还可以组合多个函数。例如要找出集合中大于5小于10的元素个数:
#include <stdlib.h>
#include <functional>
#include <vector>
#include <algorithm>
#include <iostream>
int main(void)
{
std::vector<int> vect = { 0,1,2,3,4,5,6,7,8,9 };
auto big_func = std::bind(std::less<int>(), 5, std::placeholders::_1);
auto less_func = std::bind(std::less<int>(), std::placeholders::_1, 10);
auto and_func = std::bind(std::logical_and<bool>(), big_func, less_func);
int count = std::count_if(vect.begin(),vect.end(), and_func);
std::cout << count << std::endl;
system("pause");
return 0;
}