Don't think of it as casting, think of it as the std::function<int(int)> being assigned to the std::function<void(int)> as a value.
std::function<void(int)> can be assigned any function-like object fun that can be invoked like static_cast<void>(fun(v)) (v being an int).
std::function<int(int)> easily fits that criteria since you can do:
void foo(std::function<int(int)> fun) {
fun(12);
}
So std::function<int(int)> has to be assignable to std::function<void(int)>. That's all there is to it.
How the library implements this doesn't really matter. It just has to in order to fulfil the API contract.
Disclaimer: This is a tiny bit of an oversimplification. The standard actually has a few provisions for std::function -> std::function assignment, like move-construction and dealing with unassigned std::functionss. However, the semantic principles outlined in this answer still hold as an explanation.
As asked, the relevant parts of the standard:
[func.wrap]
template function(F f);
Constraints: F is Lvalue-Callable ([func.wrap.func]) for argument types ArgTypes... and return type R.
A callable type F is Lvalue-Callable for argument types ArgTypes and return type R if the expression INVOKE(declval<F&>(), declval()...), considered as an unevaluated operand, is well-formed ([func.require]).
[func.require]
Define INVOKE(f, t
1
, t
2
, …, t
N
) as static_cast<void>(INVOKE(f, t
1
, t
2
, …, t
N
)) if R is cv void, otherwise INVOKE(f, t
1
, t
2
, …, t
N
) implicitly converted to R.
So since std::function<int(int)> is Lvalue-Callable for void(int), then it is a valid value. Now, in practice, this doesn't actually come into play because of other constructors/assignment operators will intercept it, but the semantics remain.