C++中的std::function

std::function的一些知识点,std::function可以将C++中的各种可调用对象统一包装起来,以增加程序代码通用性。

C++中的可调用对象有以下几种:函数、函数指针、lambda表达式、bind创建的对象、重载了调用运算符的类。和其它对象相同,可调用对象也有类型。如每个lambda有它自己唯一的(未命名)类类型;函数及函数指针的类型则由其返回值类型和实参类型决定等。然而,两个不同类型的可调用对象却可能共享同一中调用形式(call signature)。调用形式指明了调用返回的类型及传递给调用的实参类型。

对于几个可调用对象共享一种调用形式的情况,我们希望把它们看成具有相同的类型。此时可以使用std::function来达成这一目的,std::function位于<functional>中。function是一个模板,在创建一个具体的function类型时必须提供额外的信息,这里是指function类能表示的可调用对象的调用形式,<返回值类型(参数列表)>

以下是一个综合的示例:

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <map>
#include <functional>
class ClassMemberFunc
{
public:
static int staticAdd(int a, int b)
{
std::cout << "static member func" << std::endl;
return a + b;
};
int instanceAdd(int a, int b)
{
std::cout << "instance member func" << std::endl;
return a + b;
};
};
class ClassFunctor
{
public:
int operator()(int a, int b)
{
std::cout << "functor" << std::endl;
return a + b;
};
};
int funcAdd(int a, int b)
{
std::cout << "function" << std::endl;
return a + b;
}
int main(int argc, const char * argv[])
{
std::map<int, std::function<int(int,int)>> funcMap;
int (*fp)(int, int) = funcAdd;
auto lambdaAdd = [](int a, int b)->int{
std::cout << "lambda" << std::endl;
return a + b;
};
ClassMemberFunc cmf;
ClassFunctor cf;
auto bind = std::bind(&ClassMemberFunc::instanceAdd, cmf, std::placeholders::_1, std::placeholders::_2);
funcMap[1] = funcAdd;
funcMap[2] = fp;
funcMap[3] = lambdaAdd;
funcMap[4] = ClassMemberFunc::staticAdd;
funcMap[5] = bind;
funcMap[6] = cf;
for(int i = 1 ; i <= 6 ; i++)
{
std::cout<< "index " << i << ": ";
funcMap[i](i,1);
}
}

输出结果如下:

1
2
3
4
5
6
index 1: function
index 2: function
index 3: lambda
index 4: static member func
index 5: instance member func
index 6: functor

REFERENCE

《C++ Primer 第五版》

http://www.jellythink.com/archives/771