第6.14章: 高阶函数

English

概述

高阶函数就是接受另一个函数作为参数,或者返回一个 函数的函数。你已经见过它的构件:函数指针与无捕获的 lambda。

在本章中,你将学到:

1. 把函数传给其他函数

函数指针形参让你能把行为传入一个函数。


int operate(int a, int b, int (*op)(int, int))
{
    return op(a, b);
}

int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }

println(operate(3, 4, add)); // 7
println(operate(3, 4, mul)); // 12

这是高阶函数最简单的形式。

2. 使用无捕获 lambda 作为回调

没有捕获的 lambda 可以用在任何期望函数指针的地方。


println(operate(3, 4, [](int a, int b) { return a - b; }));

这对快速的一次性操作很有用。

3. 从函数返回函数

函数可以返回函数指针。这让你能在运行时选择行为。


int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }

int (*select_op(char c))(int, int)
{
    if(c == '+') return add;
    return sub;
}

auto op = select_op('+');
println(op(10, 3)); // 13

4. 简单的分派表

你可以把多个函数存入一个数组,并在运行时选择其中一个。


int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
int sub(int a, int b) { return a - b; }

int (*ops[3])(int, int){add, mul, sub};

println(ops[0](3, 4)); // add
println(ops[1](3, 4)); // mul
println(ops[2](3, 4)); // sub

这是解释器、状态机和命令分派器的基础。

5. 带参数的回调

回调就是传给另一个函数、以便稍后执行的函数。


void repeat(int n, void (*f)())
{
    for(int i{}; i != n; ++i)
        f();
}

repeat(3, [] { println("tick"); });

这会打印三次 tick。

要点