Skip to content

[BUG]: Overload resolution fails for derived types when single-argument overload is registered after vector overload #5716

Description

@dyollb

Required prerequisites

What version (or hash if on master) of pybind11 are you using?

3.0.0rc2

Problem description

Description:

When exposing overloaded functions in pybind11 for both std::shared_ptr<Entity> and std::vector<std::shared_ptr<Entity>>, calling the function with a derived type like std::shared_ptr<TriangleMesh> (where TriangleMesh inherits from Entity) may fail at runtime:

TypeError: object of type 'XCoreModeling.TriangleMesh' has no len()

This occurs even when class inheritance and std::shared_ptr relationships are correctly registered.

Cause:

If the vector overload is registered before the single-object overload:

m.def("func", [](const std::vector<std::shared_ptr<Entity>>& v) { func(v); });
m.def("func", [](const std::shared_ptr<Entity>& e) { func(e); });

pybind11 may mistakenly match the vector version and attempt to treat the object as a container, resulting in a len() error.

Workaround:

Switching the order of registration ensures the correct overload is selected:

m.def("func", [](const std::shared_ptr<Entity>& e) { func(e); });
m.def("func", [](const std::vector<std::shared_ptr<Entity>>& v) { func(v); });

Recommendation:

Document or improve overload resolution behavior in pybind11 when dealing with ambiguous cases involving shared pointers and containers.

Reproducible example code


Is this a regression? Put the last known working version here if it is.

Not a regression

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageNew bug, unverified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions