1.std::function可以取代函数指针的作用。因为它可以保存函数延迟执行,所以比较适合作为回调函数。
2.std::bind用来将可调用对象与其参数一起进行绑定。
3.为什么C++11加入std::function,说白了就是为了让函数对象化。那么把函数对象化的目的是什么呢?就是为了进一步深化以数据为中心(封装)的面相对象思想。(连函数都对象化了)
4.std::function的执行时间代价很大,因为要根据函数生成一个可调用的类然后再实例化出一个对象。所以说,到处都用std::function是一件很糟糕的事情。
总结:只有在使用泛型算法或者一些比较特殊的情况下才应该使用std::function,其它情况---”比如即使要写callback(函数的参数是callback函数),那么除非你要保证这个函数可以接受任何形式的函数(包括可调用对象、lambda等),否则依然建议使用函数指针、模板”,还是应该用传统的方法。
#include <stdio.h>
#include <iostream>
#include <functional>
using namespace std;
//普通函数
int func(int a)
{
cout<<__FUNCTION__<<"->"<<a<<endl;
return a;
}
//模版类函数
template <class T>
T sum(T t1, T t2)
{
cout<<__FUNCTION__<<":t1="<<t1<<","<<"t2="<<t2<<"->"<<(t1 + t2)<<endl;
return (t1 + t2);
}
//函数对象,仿函数
struct S_Mouse
{
void operator()(int a, int b)
{
cout<<"S_Mouse::"<<__FUNCTION__<<":a="<<a<<","<<"b="<<b<<endl;
}
};
//静态成员函数
class T_Model
{
public:
static void SetColor(int i)
{
m_iColor = i;
cout<<"T_Model::"<<__FUNCTION__<<":Color="<<m_iColor<<endl;
}
private:
static int m_iColor;
};
int T_Model::m_iColor = 0;
//可被转换为函数指针对象的类
struct T_Bar
{
using fr_t = void(*)(void);
operator fr_t()
{
return ptr_func;
}
static void ptr_func()
{
cout<<"T_Bar::"<<__FUNCTION__<<endl;
}
};
//回调函数实例
class T_CallBack
{
public:
T_CallBack(const std::function<void(int,int)> &f):_callback(f)
{
}
void notify(int a, int b)
{
_callback(a, b);
}
private:
std::function<void(int, int)> _callback;
};
//作为参数传递
void call_even(const std::function<int(int)> &f)
{
cout<<__FUNCTION__<<endl;
}
int main()
{
int (*func_ptr)(int) = &func; //原始函数指针
func_ptr(1);
std::function<int(int)> f1 = func; //普通函数调用
f1(2);
auto f2 = std::bind(f1, placeholders::_1); //使用std::bind功能绑定,占位符placeholders::_1
f2(3);
std::function<int(int, int)> f3 = sum<int>;//模版调用
f3(3,5);
std::function<void(int, int)> f4 = S_Mouse();//仿函数调用
f4(1,3);
std::function<void(int)> f5 = &T_Model::SetColor;//静态成员函数调用
f5(9);
T_Bar bar;
bar();
S_Mouse mouse; //普通对象调用
mouse(5,6);
S_Mouse mouse1;
T_CallBack aa(mouse1);
aa.notify(7,0);
call_even(func);//回调函数作为参数
cout<<"bind callback->";
auto f6 = std::bind(func, std::placeholders::_1); //使用绑定作为回调函数参数
call_even(f6);
return 0;
}
运行结果:
[cyh@iZn6p6j5eiblyzZ ~]$ ./test
func->1
func->2
func->3
sum:t1=3,t2=5->8
S_Mouse::operator():a=1,b=3
T_Model::SetColor:Color=9
T_Bar::ptr_func
S_Mouse::operator():a=5,b=6
S_Mouse::operator():a=7,b=0
call_even
bind callback->call_even
[cyh@iZn6p6j5eiblyzZ ~]$