cpp11-function

类模版std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的)。

通过std::function对C++中各种可调用实体(普通函数、Lambda表达式、函数指针、以及其它函数对象等)的封装,形成一个新的可调用的std::function对象;让我们不再纠结那么多的可调用实体。

#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';
}

struct PrintNum {
void operator()(int i) const
{
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;
const Foo foo(314159);
f_add_display(foo, 1);
f_add_display(314159, 1);

// 存储到数据成员访问器的调用
std::function<int(Foo const&)> f_num = &Foo::num_;
std::cout << "num_: " << f_num(foo) << '\n';

// 存储到成员函数及对象的调用
using std::placeholders::_1;
std::function<void(int)> f_add_display2 = std::bind( &Foo::print_add, foo, _1 );
f_add_display2(2);

// 存储到成员函数和对象指针的调用
std::function<void(int)> f_add_display3 = std::bind( &Foo::print_add, &foo, _1 );
f_add_display3(3);

// 存储到函数对象的调用
std::function<void(int)> f_display_obj = PrintNum();
f_display_obj(18);
}

关于可调用实体转换为std::function对象需要遵守以下两条原则:
转换后的std::function对象的参数能转换为可调用实体的参数;
可调用实体的返回值能转换为std::function对象的返回值。
它不能被用来检查相等或者不相等,但是可以与NULL或者nullptr进行比较。