std::function和std::bind可以让标准函数的使用更方便,也可以实现延迟求值。
1.可调用对象
1.1函数指针
1.2具有operator()成员函数的类对象(仿函数,重载()符号类的对象)
1.3可以被转换为函数指针的类对象
1.4类成员函数指针,类成员指针
void func(void)
{
...
}
struct Foo
{
void operator() (void)
{
...
}
};
struct Eoo
{
using fr = void(*)(void);
static void func(void)
{
...
}
operator fr()
{
return func;
}
};
struct Goo
{
int a;
void mem_func(void)
{
...
}
};
int main()
{
void (* func_ptr) (void) = &func; // 函数指针
func_ptr(); // 调用函数指针
Foo foo; // 仿函数
foo(); // 调用仿函数
Eoo eoo; // 可被转换为函数指针的类对象
eoo(); // 调用类对象
void (Goo::*mem_func_ptr)(void) = &Goo::mem_func;
// 类成员函数指针
int Goo::*men_obj_ptr = &Goo::a; // 类成员指针
Goo goo;
(goo.*men_func_ptr)(); // 调用类成员函数指针
goo.*men_obj_ptr = 123; // 调用类成员指针
return 0;
}
2.定义:
std::function是可调用对象的包装器。是一个类模板,可以容纳除了类成员函数指针、类成员指针以外的所有可调用对象。
3.使用方式:
当给std::function填入合适的函数签名int(int),它就变成一个可以容纳此类型调用方式的“函数包装器”。
#include <iostream>
#include <functional>
void func()
{
std::cout << __FUNCTION__ << std::endl;
}
class Foo
{
public:
static int foo_func(int a)
{
std::cout << __FUNCTION__ << "("<< a << ")->";
return a;
}
private:
};
class Bar
{
public:
int operator()(int a)
{
std::cout << __FUNCTION__ << "(" << a << ")->";
return a;
}
private:
};
int main() {
std::function<void(void)> fr1 = func; // 函数指针
fr1();
std::function<int(int)> fr2 = Foo::foo_func; // 类静态函数
std::cout << fr2(123) << std::endl;
Bar bar;
std::function<int(int)> fr3 = bar; // 重载()运算符的类对象
std::cout << fr3(456) << std::endl;
return 0;
}
函数指针的调用,取代了函数指针
#include <iostream>
#include <functional>
class MyClass
{
std::function<void()> callbackMy;
public:
MyClass(const std::function<void()> &f)
:callbackMy(f)
{
}
void Notify()
{
callbackMy(); // 注意,此处一定带有()才是真的调用。
}
};
class Bar
{
public:
void operator()()
{
std::cout << __FUNCTION__ << std::endl;
}
};
int main() {
Bar bar;
MyClass my(bar);
my.Notify();
return 0;
}
函数入参
#include <iostream>
#include <functional>
void call_when_event(int x, const std::function<void(int)> &f)
{
if ( x% 2 == 0)
{
f(x);
}
}
void output(int x)
{
std::cout << x << std::endl;
}
int main() {
for (int i = 1; i < 10 ; ++i)
{
call_when_event(i,output);
}
return 0;
}