01 可调用对象的种类
// 01 函数指针
void CallableObject01() {}
// 02 重载 operator() 运算符的结构体/类对象
struct CallableObject02
{
void operator()() {}
};
// 03 可以被转换为函数指针的结构体/类对象
struct CallableObject03
{
using func_t = void(*)();
static void func() {}
operator func_t() { return func; }
};
// 04 结构体/类成员函数指针
struct CallableObject04
{
void func() {}
};
// 05 Lambda 表达式
auto CallableObject05 = []() {};
Lambda 的更多介绍请移步:C++11 Lambda 表达式
02 可调用对象的操作
std::function
std::function 是一个类模版,可以容纳除了类成员函数的指针之外的所有可调用对象。
通过指定 std::function 的模板参数,可以使用统一的方式处理函数指针、函数对象、静态成员函数、Lambda 表达式,并允许保存和延迟它们:
// 可调用对象的定义同上
#include <functional>
std::function<void()> func01 = CallableObject01;
CallableObject02 oc02;
std::function<void()> func02 = oc02;
CallableObject03 co03;
std::function<void()> func03 = co03;
std::function<void()> func04 = CallableObject03::func;
std::function<void()> func05 = []() {};
std::bind
std::bind 用于将可调用对象及其参数一起绑定。绑定后的结果可以使用 std::bind 进行保存,并延迟调用到任何需要的时候。
std::bind 可以绑定函数的部分参数。
// 可调用对象的定义同上
void CallableObject06(int n) {}
struct CallableObject07
{
void func(int n) {}
};
struct CallableObject08
{
using func_t = void(*)(int);
static void func(int n) {}
operator func_t() { return func; }
};
// auto = std::function<void(int)>
auto bfunc01 = std::bind(CallableObject06, std::placeholders::_1);
CallableObject07 oc7;
auto bfunc02 = std::bind(&CallableObject07::func, oc7, std::placeholders::_1);
CallableObject08 oc8;
auto bfunc03 = std::bind(&CallableObject08::func, std::placeholders::_1);
std::placeholders::_n 代表一个占位符,表示这个位置在函数调用时会被传入的第 n 个参数代替。
void func(int m, int n)
{
std::cout << m << " " << n << std::endl;
}
std::bind(func, 1, 2)(); // 1 2
std::bind(func, std::placeholders::_1, 2)(1); // 1 2
std::bind(func, 1, std::placeholders::_1)(2); // 1 2
std::bind(func, std::placeholders::_1, 2)(1); // 1 2
std::bind(func, std::placeholders::_1, std::placeholders::_2)(1, 2);
// 1 2
// std::bind(func, 1, std::placeholders::_2)(1); // error: 缺少实参:需要将第二个传如的实参作为调用函数的参数
std::bind(func, 1, std::placeholders::_2)(1, 2); // 1 2