pybind / pybind/pybind11

[QUESTION]: BUG or FEATURE? overload_cast doesn't work for auto deduced return type functions templates

Open
#3,174 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

compiler issue
Dominant language
C++
Stars
18k
Forks
2.3k
Avg merge
5d 17h
Merged PRs (30d)
10

Description

Required prerequisites
Problem description

When an overloaded member function's return type is auto deduced, and the class is a template, overload_cast fails to deduce return type.

  In file included from /tmp/pip-build-env-n9g56e9j/overlay/lib/python3.9/site-packages/pybind11/include/pybind11/pytypes.h:12,
                   from /tmp/pip-build-env-n9g56e9j/overlay/lib/python3.9/site-packages/pybind11/include/pybind11/cast.h:13,
                   from /tmp/pip-build-env-n9g56e9j/overlay/lib/python3.9/site-packages/pybind11/include/pybind11/attr.h:13,
                   from /tmp/pip-build-env-n9g56e9j/overlay/lib/python3.9/site-packages/pybind11/include/pybind11/pybind11.h:23,
                   from src/doublePet.cpp:1:
  /tmp/pip-build-env-n9g56e9j/overlay/lib/python3.9/site-packages/pybind11/include/pybind11/detail/common.h:843:20: note: candidate: ‘template<class Return, class Class> constexpr decltype (pmf) pybind11::detail::overload_cast_impl<Args>::operator()(Return (Class::*)(Args ...) const, std::true_type) const [with Return = Return; Class = Class; Args = {const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&}]’
    843 |     constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept
        |                    ^~~~~~~~
  /tmp/pip-build-env-n9g56e9j/overlay/lib/python3.9/site-packages/pybind11/include/pybind11/detail/common.h:843:20: note:   template argument deduction/substitution failed:
  src/doublePet.cpp:37:59: note:   types ‘Return (Class::)(const std::__cxx11::basic_string<char>&) const’ and ‘double (Pet<double>::)(double)’ have incompatible cv-qualifiers
     37 |         .def("set", py::overload_cast<const std::string &>(&doublePet::set), "Set the pet's name");
        |                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
  src/doublePet.cpp:37:59: note:   candidate expects 2 arguments, 1 provided
Reproducible example code
#include "pybind11/pybind11.h"
namespace py = pybind11;

template <typename T>
struct Pet
{
    Pet(const std::string &name, T age) : name(name), age(age) {}

    auto set(T age_)
    {
        age = age_;
        return age;
    }
    auto set(const std::string &name_)
    {
        name = name_;
        return name;
    }

    std::string name;
    T age;
};
using doublePet = Pet<double>;

void bind_pet(py::module &m)
{
    py::class_<doublePet>(m, "doublePet")
        .def("set", py::overload_cast<double>(&doublePet::set), "Set the pet's age")
        .def("set", py::overload_cast<const std::string &>(&doublePet::set), "Set the pet's name");
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the overload_cast implementation and the candidate signatures shown in pybind11/detail/common.h, then reproduce the failure using the Pet template example from the issue. Trace why the auto-deduced member functions are not accepted and determine whether the behavior should be fixed or documented. Done means the issue has a clear resolution backed by an appropriate regression check or documentation update.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.