函数指针混淆:在 C++ 中制作函数调度器

Function pointer confusion: Making a function dispatcher in C++

我有一个函数作为 "function dispatch." 这个函数包含一个名为 next_func 的变量,它被初始化为要加载的第一个函数。然后,在无限循环中,next_func 被设置为自身的 return 值。

我的问题是,除了使用autonext_func还需要什么类型?这里有一些概念代码(使用auto)来说明我在寻找什么:

void FunctionDispatch()
{
    auto next_menu = first_menu;
    while (next_menu != app_exit)
    {
        next_menu = next_menu();
    }
}

auto first_menu()
{
    auto return_menu = first_menu; // Set to itself for 'auto', but I don't want to have to do this

    std::cout << "2 or 3? ";
    unsigned input = 0;
    std::cin >> input;

    switch (input)
    {
    case 2:
        return_menu = second_menu;
        break;

    case 3:
        return_menu = third_menu;
        break;

    default:
        break;
    }

    return return_menu;
}

我喜欢将 auto 用于琐碎的类型,但我不太喜欢依赖它,因为我不知道如何处理我想要的类型,这就是我想知道的原因auto 实际上是什么以及如何显式声明变量和函数 return 类型(可能使用类型别名,因为这是最明智的)。

注意事项:

首先,酷!这让我想起了中间件框架,或者带有任务和事件循环的协程。

如许多人所提到的,使用直接函数指针执行此操作将导致无限递归类型。但是,如果每个任务都是一个可调用对象,那么您就不需要像前向引用那样的递归类型。您可以继承 std::function 以使其变得简单:

struct task : std::function<task()> {
    using std::function<task()>::function;
};

然后你就可以给它分配功能了。您还可以使用 std::bind 绑定参数,甚至可以使用默认构造函数创建一个没有目标的空函数:

task n_hellos(int count) {
    if (count) {
        std::cout << "hello\n";
        return std::bind(n_hellos, count-1);
    }
    return task();
}

您可以将 std::function 转换为 bool 以查看它是否为空,从而允许终端情况。当下一个任务为空时,下面的事件循环退出:

int main() {
    task current_task = std::bind(n_hellos, 5);
    while (current_task) {
        current_task = current_task();
    }
} // prints "hello" five times

演示:https://godbolt.org/z/dHaSWC