pybind11
pybind11 copied to clipboard
Bug with inheritance, shared_ptr holder and enable_shared_from_this
Issue description
error C2683: 'dynamic_cast': 'base' is not a polymorphic type
If base derives from std::enable_shared_from_this, pybind11 uses dynamic_cast, even if type is not polymorphic.
Reproducible example code
#include <memory>
#include <pybind11/pybind11.h>
struct base : public std::enable_shared_from_this<base>
{
};
struct derived : base
{
};
void python_export(pybind11::module& m)
{
pybind11::class_<base, std::shared_ptr<base>>(m, "Base")
.def(pybind11::init<>())
;
pybind11::class_<derived, base, std::shared_ptr<derived>>(m, "Derived")
.def(pybind11::init<>())
;
}
Confirmed on my side, due to this code: https://github.com/pybind/pybind11/blob/a1b71df137e015d44f7e31f7b6d4807253fb7871/include/pybind11/pybind11.h#L1294
As a workaround, is it too painful to make the interface (artificially) virtual?
As a fix, I guess that cast could be delegated to a special-casing, where if the type is polymorphic, use dynamic_cast, but if not, just rely on static_cast (and cross your fingers that multiple inheritance wasn't used?).
As a peanut gallery comment, I was gonna say that I believe pybind11 relies on the fact that inheritance implies polymorphism, but reading the docs, I was wrong... d'oh!
https://pybind11.readthedocs.io/en/stable/classes.html#inheritance-and-automatic-upcasting
Any news on this? The error is not the same but is still there. I'd love to switch to pybind11 but this is a no-go, unless there is a viable workaround.
Can someone take a look at this again? Inheritance of types with shared_ptr holders is broken.