Why function pointer of overloaded function need static_cast?

std::function<void(A, int)> is more complicated than void(*)(A, int).

template< class F >
function( F f );

Initializes the target with std::move(f). If f is a null pointer to function or null pointer to member, *this will be empty after the call. This constructor does not participate in overload resolution unless f is Callable for argument types Args... and return type R.

You don't even know what constructors participate in overload resolution until you decide which N::func you mean.

One can conceive of an combined overload resolution and template argument deduction scheme that could "meet in the middle" by trying std::function<void(A, int)>::function<void(*)(A, int)> among (arbitrarily many) other valid instantiations of the constructor.

Problems abound with that.

  1. It has to provably arrive at an answer. In general there are infinite possible instantiations of the templates. You'd also want it to be able to pick int(*)(A, int) if you passed it int g(A, int).
  2. It really should agree with the current scheme where that arrives at an unambiguous answer.
  3. Each of the compiler vendors have to implement it correctly.

As a handy workaround you can provide this kind of func_1 overload.

...

void func_1(void(*x)(A, int))
{
    func_1(std::function<void(A, int)>{x});
}

Now it works as desired without static_cast: demo