In C ++ 11, the std::function constructor, which takes an arbitrary type of functor, is specified as (quoting N3337 ยง20.8.11.2.1 [func.wrap.func.con] / p7):
template<class F> function(F f); template <class F, class A> function(allocator_arg_t, const A& a, F f);
7 Requires: F must be CopyConstructible . F must be Callable (20.8.11.2) for the argument types ArgTypes and return type R copy constructor and destructor A should not throw exceptions.
Violating the Requires clause (passing F not Callable for Callable argument ArgTypes and R return type) is undefined behavior, so the library can do whatever it wants, in this case, the Library can deduce the constructor from overload resolution, but this is not necessary, and if this is not so, then you will have problems with overload resolution and std::is_convertible - it will report that almost everything under the sun is converted to std::function (including stuff like double !).
Therefore, in LWG issue 2132, the standard was changed to require an implementation to remove these constructors from overload resolution (via SFINAE or a similar technique) if the functor is not Callable for the specified argument types and return type. Now it reads:
template<class F> function(F f); template <class F, class A> function(allocator_arg_t, const A& a, F f);
7 Requires: F must be CopyConstructible .
8 Notes: These constructors should not participate in overloading if F is Callable (09/20/11) for argument types ArgTypes... and return type R
So, if your standard library implements this permission, then std::is_convertible<std::function<void(int)>, std::function<void()>>::value - false . Otherwise, it is implementation dependent.
I would suggest that when these functions return to the truth, a transformation can be made. Or am I missing something?
Typical traits, such as std::is_convertible , std::is_constructible or std::is_assignable , take into account only the immediate context - that is, whether there is a corresponding function signature that is accessible and not deleted. They do not check if the function body will compile when instantiated.