pybind11 icon indicating copy to clipboard operation
pybind11 copied to clipboard

Bug with inheritance, shared_ptr holder and enable_shared_from_this

Open Boris-Rasin opened this issue 6 years ago • 2 comments

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<>())
	;
}

Boris-Rasin avatar May 22 '19 00:05 Boris-Rasin

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

eacousineau avatar Jun 19 '19 12:06 eacousineau

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.

Holt59 avatar Apr 18 '22 15:04 Holt59

Can someone take a look at this again? Inheritance of types with shared_ptr holders is broken.

aditya-283 avatar Feb 08 '23 00:02 aditya-283