Object slicing happens here.
The point is given f = *p;, p is of type std::shared_ptr<Foo>, then the type of *p is Foo& (instead of Bar&). Even the assignment operator of std::function takes argument by reference, but
4) Sets the target of
*thisto the callablef, as if by executingfunction(std::forward<F>(f)).swap(*this);.
Note that the F above is deduced as Foo& too. And the constructor of std::function takes argument by value, object slicing happens, the effect becomes that f is assigned from an object of type Foo which is slice-copied from *p.
template< class F > function( F f );