A while ago I used std::function pretty much like this:
std::function func = [](int i) -> int { return i; };
Your code has undefined behavior. It may or may not work as you expect. The reason it has undefined behavior is because of 20.8.11.2.1 [func.wrap.func.con]/p7:
Requires:
Fshall beCopyConstructible.fshall be Callable (20.8.11.2) for argument typesArgTypesand return typeR.
For f to be Callable for return type R, f must return something implicitly convertible to the return type of the std::function (void in your case). And int is not implicitly convertible to void.
I would expect your code to work on most implementations. However on at least one implementation (libc++), it fails to compile:
test.cpp:7:30: error: no viable conversion from 'int (int)' to 'std::function'
std::function ff = f;
^ ~
Ironically the rationale for this behavior stems from another SO question.
The other question presented a problem with std::function usage. The solution to that problem involved having the implementation enforce the Requires: clause at compile time. In contrast, the solution to this question's problem is forbidding the implementation from enforcing the Requires: clause.