首页 > 解决方案 > 仿函数可以总是替换回调吗

问题描述

在 C++ 中,仿函数可以总是替换回调吗?或者在某些情况下需要“常规”回调?即每个接受函数指针的函数,取而代之的是一个仿函数,具有与函数指针相同的参数和返回值?

标签: c++callbackfunctor

解决方案


传统的 C 函数指针不能仅使用任何仿函数来替换。因此,具有operator()重载的结构或具有捕获变量的 lambda 将不起作用。请参阅以下代码:

#include <functional>

// this function takes a void() function pointer
void run_callback(void(*callback)()) {
    callback();
}

// this function takes a std::function
void run_function(std::function<void()> fun) {
    fun();
}

struct Callable {
    void operator()();
};

int main() {
    int x;
    run_callback([](){});     // OK
    run_callback([x](){});    // ERROR, we are not allowed to capture x
    run_callback(Callable{}); // ERROR, can't convert Callable to function pointer

    run_function([](){});     // OK
    run_function([x](){});    // ALSO OK
    run_function(Callable{}); // ALSO OK
}

如果您想要一个仅适用于从函数指针到 lambdas/functors 的解决方案,请使用std::function.

从 C++ 调用 C API 时需要 C 函数指针。

C 函数指针在性能关键的应用程序中也更好。 std::function可以接受任何东西,因为在内部,它将函数指针和函子包装在多态包装类中。这需要一个虚函数调用,这意味着std::function在它知道要调用什么之前需要取消引用一个指针。也std::function可以为空。因此,它需要测试每个调用是否为空,std::bad_function_call如果是则抛出。


推荐阅读