Традиционные C указатели на функции не могут быть заменены с помощью любого функтора. Таким образом, структуры с перегрузками operator()
или лямбда-выражения с переменными захвата работать не будут. См. Следующий код:
#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
}
Если вам нужно решение, которое работает для чего угодно, от указателей на функции до лямбда-выражений / функторов, используйте std::function
.
C указатели на функции необходимо при вызове C API из C ++.
C указатели на функции также лучше подходят для приложений, критичных к производительности. std::function
может принимать что угодно, потому что внутри он обертывает указатели на функции и функторы в класс-оболочку polymorphi c. Для этого требуется вызов виртуальной функции, а это означает, что std::function
необходимо разыменовать указатель, прежде чем он узнает, что вызывать. Также std::function
может быть пустым. В результате ему необходимо проверять каждый вызов, является ли он пустым, и выдает std::bad_function_call
, если это так.