CXX可调用对象

这篇笔记记录function模板与含有相同调用形式的可调用对象。

c++中有一些可调用对象

  • 函数
  • 函数指针
  • lambda
  • bind创建的对象
  • 重载了函数调用运算符的类

比如下面三个函数add, mod, divide

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <functional>
#include <unordered_map>
using namespace std;

//一般函数
int add(int a, int b){ return a+b; }

//命名的lambda函数
auto mod = [](int a, int b){ return a%b; };

//重载了调用运算符的类,又称作函数对象
struct divide{
int operator()(int denomenator, int divisor){
return denomenator/divisor;
}
};

三个不同可调用对象:普通函数add,命名了的lambda对象mod,函数对象(function object)divide 拥有相同的调用形式(call signature).

1
int (int, int)   //表示传入两个int型,返回一个int型

而模板类function使用时需要指定类型,如上述调用形式。如此可以定义多个function对象

1
2
3
4
5
6
7
8
9
10
11
12
13
int main(int argc, char** argv){    
function<int(int, int) > f1 = add;
function<int(int, int) > f2 = divide();
function<int(int, int) > f3 = [](int a, int b){ return a%b; };
function<int(int, int) > f4 = mod;

cout<<f1(4,2)<<endl;
cout<<f2(4,2)<<endl;
cout<<f3(4,2)<<endl;
cout<<f4(4,2)<<endl;

return 0;
}

接下来, 可以构建从算数符号到函数的映射,如

1
2
3
4
5
6
7
8
9
10
11
12
13
//加入main中
unordered_map<string, function<int(int,int)>> calculator = {
{"+", add}, //函数指针
{"-", std::minus<int>()}, //STL函数
{"*", [](int a, int b){ return a*b; }}, //匿名lambda函数
{"/", divide()}, //函数对象
{"%", mod} }; //命名的lambda函数

calculator["+"](10,5);
calculator["-"](10,5);
calculator["*"](10,5);
calculator["/"](10,5);
calculator["%"](10,5);

如同vector<int>可以作为容器内容的类型,此处只不过用function<int(int,int)>作为了map的val类型。

结束
c++可调用对象