TL DR;
FailsForF2fails because it is std::unique_ptr<Derived> (*) ()implicitly converted to std::unique_ptr<Base> (*) ();Works , std::unique_ptr<Derived> std::unique_ptr<Base> (. ).
1 :
std::unique_ptr<Base> (*) ()
std::unique_ptr<Derived> (*) ()
std::unique_ptr<Base> (*) ()
std::unique_ptr<Derived> (*) () ( ) std::unique_ptr<Base> (*) (), FailsForF2. . :
std::unique_ptr<Derived> (*pfd) () = f2;
std::unique_ptr<Base> (*pfb) () = pfd;
, ( , . ), .
std::function, , . std::function , :
template <typename F>
std::function(F &&f);
... : 2:
INVOKE(f, std::forward<Args>(args)..., R)
1 N4594, 5.1.5/7 ( ):
- - - ++ (7.5), . [...] >
2 N4594, & sect; 20.12.12.2/2:
f F ArgTypes R, INVOKE (f, declval<ArgTypes>()..., R), ( 5), (20.12.2). >
... & sect; 20.12.2 ( , 1.1 1.6 ( ) -, ):
1 INVOKE (f, t1, t2, ..., tN) :
(1.x) - [...]
(1.7) - f(t1, t2, ..., tN) .
2 INVOKE (f, t1, t2, ..., tN, R) static_cast (INVOKE (f, t1, t2, ..., tN)), R cv void, INVOKE (f, t1, t2, ..., tN) R.