What is the difference between different ways of passing a function as an argument to another function?

nor*_*ner 8 c++ function parameter-passing

I have the situation where one function calls one of several possible functions. This seems like a good place to pass a function as a parameter. In this Quoara answer by Zubkov there are three ways to do this.

int g(int x(int)) { return x(1); }
int g(int (*x)(int)) { return x(1); }
int g(int (&x)(int)) { return x(1); }
...
int f(int n) { return n*2; }
g(f); // all three g's above work the same
Run Code Online (Sandbox Code Playgroud)

When should which method be used? What are there differences? I prefer the simplest approach so why shouldn't the first way always be used?

For my situation, the function is only called once and I'd like to keep it simple. I have it working with pass by pointer and I just call it with g(myFunc) where myFunc is the function that gets called last.

Eri*_*ric 3

扩展 LF 的评论,通常最好完全避开函数指针,并根据可调用对象(定义的事物operator())进行工作。以下所有内容都允许您执行此操作:

#include <type_traits>

// (1) unrestricted template parameter, like <algorithm> uses
template<typename Func>
int g(Func x) { return x(1); }

// (2) restricted template parameter to produce possibly better errors
template<
    typename Func,
    typename=std::enable_if_t<std::is_invocable_r_v<int, Func, int>>
>
int g(Func x) { return std::invoke(x, 1); }

// (3) template-less, trading a reduction in code size for runtime overhead and heap use
int g(std::function<int(int)> x) { return x(1); }
Run Code Online (Sandbox Code Playgroud)

重要的是,所有这些都可以在带有捕获的 lambda 函数上使用,这与您的任何选项不同:

int y = 2;
int ret = g([y](int v) {
    return y + v;
});
Run Code Online (Sandbox Code Playgroud)