将函数对象赋值给std::function后意外行为的原因问询
Let's break down exactly what's happening in your code, step by step:
1. Why (*p)() outputs 2 (expected behavior)
When you dereference std::shared_ptr<Foo> p with *p, you get a Foo& reference that binds directly to the underlying Bar object. Since operator() is a virtual function, C++ uses dynamic dispatch (via the vtable) to resolve the call to the Bar implementation, hence the output is 2. This is standard polymorphic behavior working as intended.
2. Why f = *p leads to outputting 1 (unexpected object slicing)
Here's the critical issue: std::function<int(void)> stores a copy of the callable object by default, not a reference. When you assign *p (which has a static type of Foo&) to f, the compiler only sees a reference to the base class Foo.
This means std::function will create a copy of the object as a pure Foo instance, stripping away all Bar-specific data and behavior—this is called object slicing. When you call f(), you're invoking operator() on a standalone Foo object, so the base class implementation is executed, resulting in output 1.
3. Why Bar b; std::function<int(void)> f1 = b outputs 2
In this scenario, you're assigning a Bar object directly to std::function. The compiler's static type check recognizes the object as Bar, so std::function copies a full Bar instance into its internal storage. When you call f1(), even though operator() is virtual, the stored object is a complete Bar instance, so dynamic dispatch correctly calls the Bar implementation, outputting 2.
To put it simply: The slicing happens because *p presents itself as a Foo reference to the compiler, so std::function copies only the base class part. Directly assigning a Bar object avoids this because the static type matches the actual object type.
内容的提问来源于stack exchange,提问作者Rabbid76

