typedef boost::function my_func 是什么玩意?

声明:以下内容纯属瞎编。

背景

有人问下面的一行代码是什么鬼:

typedef boost::function<bool(const std::string& hostname, std::vector<std::string>* ips)> ResolveFn;

我也不知道啊,但是要百度一下装得自己知道的样子。这玩意其实是定义一种函数的类型。

函数是啥?

当我们定义一个函数,其实是写了一个代码段。

int square(int x){
    return x*x;
}

square 这个名字本身只是指向这个函数(代码段)的指针。比如:

printf("%p\n", square);
-> 0x401256

这个“函数指针”是有类型的:square 是一个接受1个int输入,输出int的函数。我们可以表示成 int(int), 即 return_type(arg1, arg2, ...).

当我们加上括号,square()则是另一个含义:调用(call)这个函数。()在代码里做的是 call 这个动作。

square(2)
-> 4

typedef 是啥?

typedef 通常用于定义一个类型。比如,可以把 long long int 定义为 super_int,相当于给一个复杂的类型取一个简单的名字。

typedef long long int super_int;

示例程序:

// filename: test.cpp
#include <boost/function.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

typedef int crazy_type;

int main()
{
    crazy_type num = 0;
    cout << num << '\n';
    num = 1;
    cout << num << '\n';
    return 0;
}

这个程序中,定义一个 crazy_type 的类型,其实它只是个 int.

输出:

$ g++ -Wall test.cpp -o test
$ ./test
0
1

给函数指针定义类型

刚刚提到, int square(int x) 这个函数的类型是 int(int),我们可以把拥有这类输入输出的函数定义为 int_func 类型。
之后,我们可以定义一个“函数指针” func_pointer,专门指向 int(int) 类的函数。
后面,修改 func_pointer 的目标地址,就能改变 func_pointer 实际调用的代码。

示例程序:

// filename: test.cpp
#include <boost/function.hpp>
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

typedef boost::function<int(int)> int_func;

int square(int x){
    return x*x;
}

int cube(int x){
    return x*x*x;
}

int main()
{
    int_func func_pointer;

    func_pointer = square;
    cout << func_pointer(2) << '\n';

    func_pointer = cube;
    cout << func_pointer(2) << '\n';
    return 0;
}

输出:

$ g++ -Wall test.cpp -o test
$ ./test
4
8

小结

所以,最开始的一行说的是:
- 定义一个叫 ResolveFn 的“函数指针”类型。
- 属于 ResolveFn 类型的函数,它接受两个输入,一个是 string &hostname, 一个是 vector *ips, 它的返回值是 bool.

typedef boost::function<bool(const std::string& hostname, std::vector<std::string>* ips)> ResolveFn;

- 后续,如果看到一个指针的类型是 ResolveFn, 那么这个指针是指向一个有这样输入输出的函数。

参考文档

https://theboostcpplibraries.com/boost.function
https://www.eskimo.com/~scs/cclass/int/sx10a.html
http://www.radmangames.com/programming/how-to-use-function-pointers-in-cplusplus
https://stackoverflow.com/questions/11038430/how-to-create-a-typedef-for-function-pointers