在C++ 11中,callable object 包括传统C函数,C++成员函数,函数对象(实现了()运算符的类的实例),lambda表达式(特殊函数对象)共4种。程序设计,特别是程序库设计时,经常需要涉及到回调,如果针对每种不同的callable object单独进行声明类型,代码将会非常散乱,也不灵活。如下示例:
#include <iostream>
#include <functional>
using namespace std ;
int c_function(int a, int b)
{
return a + b;
}
class Functor
{
public :
int operator ()(int a, int b)
{
return a + b;
}
};
int main(int argc, char ** argv)
{
int (*f)(int , int );
f = c_function;
cout << f(3 , 4 ) << endl;
Functor ff = Functor();
cout << ff(3 , 4 ) << endl;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
幸运的是,C++标准库的头文件里定义了std::function<>模板,此模板可以容纳所有类型的callable object.示例代码如下:
#include <iostream>
#include <functional>
using namespace std ;
int c_function(int a, int b)
{
return a + b;
}
class Functor
{
public :
int operator ()(int a, int b)
{
return a + b;
}
};
int main(int argc, char ** argv)
{
std ::function<int (int , int )> callableObject;
callableObject = c_function;
cout << callableObject(3 , 4 ) << endl;
Functor functor;
callableObject = functor;
cout << callableObject(3 , 4 ) << endl;
callableObject = [](int a, int b){
return a + b;
};
cout << callableObject(3 , 4 ) << endl;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
std::function<>的这种多态能力确实很强,这样可以定义一个回调列表,而列表的元素可接受的可调用物类型并不相同。如下:
#include <iostream>
#include <functional>
#include <list>
using namespace std ;
int c_function(int a, int b)
{
return a + b;
}
class Functor
{
public :
int operator ()(int a, int b)
{
return a + b;
}
};
int main(int argc, char ** argv)
{
Functor functor;
std ::list <std ::function<int (int , int )> > callables;
callables.push_back(c_function);
callables.push_back(functor);
callables.push_back([](int x, int y)->int {
return x + y;
});
for (const auto & e : callables)
{
cout << e(3 , 4 ) << endl;
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
对于使用C回调机制的程序库来说,C++的std::function<>能兼容传统C函数指针,所以库这一端使用std::function<>代替函数指针,并不会影响旧有客户端程序的编码方式。
转载地址:http://blog.csdn.net/smstong/article/details/44958833