diff --git a/include/pybind11/detail/smart_holder_poc.h b/include/pybind11/detail/smart_holder_poc.h index 15f4c1af4..0448c1d14 100644 --- a/include/pybind11/detail/smart_holder_poc.h +++ b/include/pybind11/detail/smart_holder_poc.h @@ -101,6 +101,16 @@ inline bool is_std_default_delete(const std::type_info &rtti_deleter) { || rtti_deleter == typeid(std::default_delete); } +inline void enable_shared_from_this_from_raw_ptr_take_ownership_guard(...) {} + +template +inline void enable_shared_from_this_from_raw_ptr_take_ownership_guard( + const std::enable_shared_from_this *) { + // This static_assert will always trigger if this template function is instantiated. + static_assert(!std::is_base_of, AnyBaseOfT>::value, + "Ownership must not be transferred via a raw pointer."); +} + struct smart_holder { const std::type_info *rtti_uqp_del = nullptr; std::shared_ptr vptr; @@ -235,8 +245,7 @@ struct smart_holder { template static smart_holder from_raw_ptr_take_ownership(T *raw_ptr) { - static_assert(!std::is_base_of, T>::value, - "Ownership must not be transferred via a raw pointer."); + enable_shared_from_this_from_raw_ptr_take_ownership_guard(raw_ptr); ensure_pointee_is_destructible("from_raw_ptr_take_ownership"); smart_holder hld; hld.vptr.reset(raw_ptr, make_guarded_builtin_delete(true)); diff --git a/tests/test_class_sh_shared_from_this.cpp b/tests/test_class_sh_shared_from_this.cpp index dde592f18..84cbe1215 100644 --- a/tests/test_class_sh_shared_from_this.cpp +++ b/tests/test_class_sh_shared_from_this.cpp @@ -52,7 +52,7 @@ TEST_SUBMODULE(class_sh_shared_from_this, m) { m.def("print_myobject3_1", [](const MyObject3 *obj) { py::print(obj->toString()); }); m.def("print_myobject3_2", [](std::shared_ptr obj) { py::print(obj->toString()); }); m.def("print_myobject3_3", [](const std::shared_ptr &obj) { py::print(obj->toString()); }); - //m.def("print_myobject3_4", [](const std::shared_ptr *obj) { py::print((*obj)->toString()); }); + // m.def("print_myobject3_4", [](const std::shared_ptr *obj) { py::print((*obj)->toString()); }); using B = SharedFromThisRef::B; // py::classh(m, "B"); @@ -69,6 +69,6 @@ TEST_SUBMODULE(class_sh_shared_from_this, m) { .def("set_holder", [](SharedFromThisRef &, std::shared_ptr) { return true; }); static std::shared_ptr sft(new SharedFromThisVirt()); - py::classh(m, "SharedFromThisVirt") - .def_static("get", []() { return sft.get(); }, py::return_value_policy::reference); + // py::classh(m, "SharedFromThisVirt") + // .def_static("get", []() { return sft.get(); }, py::return_value_policy::reference); }