mirror of
https://github.com/pybind/pybind11.git
synced 2026-04-19 22:39:09 +00:00
Use dynamic cast for shared_from_this holder init
Using a dynamic_cast instead of a static_cast is needed to safely cast from a base to a derived type. The previous static_pointer_cast isn't safe, however, when downcasting (and fails to compile when downcasting with virtual inheritance). Switching this to always use a dynamic_pointer_cast shouldn't incur any additional overhead when a static_pointer_cast is safe (i.e. when upcasting, or self-casting): compilers don't need RTTI checks in those cases.
This commit is contained in:
@@ -214,6 +214,12 @@ struct SharedFromThisRef {
|
||||
std::shared_ptr<B> shared = std::make_shared<B>();
|
||||
};
|
||||
|
||||
// Issue #865: shared_from_this doesn't work with virtual inheritance
|
||||
struct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {
|
||||
virtual ~SharedFromThisVBase() = default;
|
||||
};
|
||||
struct SharedFromThisVirt : virtual SharedFromThisVBase {};
|
||||
|
||||
template <typename T>
|
||||
class CustomUniquePtr {
|
||||
std::unique_ptr<T> impl;
|
||||
@@ -258,6 +264,11 @@ test_initializer smart_ptr_and_references([](py::module &pm) {
|
||||
.def("set_ref", [](SharedFromThisRef &, const B &) { return true; })
|
||||
.def("set_holder", [](SharedFromThisRef &, std::shared_ptr<B>) { return true; });
|
||||
|
||||
// Issue #865: shared_from_this doesn't work with virtual inheritance
|
||||
static std::shared_ptr<SharedFromThisVirt> sft(new SharedFromThisVirt());
|
||||
py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(m, "SharedFromThisVirt")
|
||||
.def_static("get", []() { return sft.get(); });
|
||||
|
||||
struct C {
|
||||
C() { print_created(this); }
|
||||
~C() { print_destroyed(this); }
|
||||
|
||||
Reference in New Issue
Block a user