[BUG]: overload cast for function with template option failing on clang
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 18k
- Forks
- 2.3k
- Avg merge
- 5d 17h
- Merged PRs (30d)
- 10
Description
Required prerequisites
- Make sure you've read the documentation. Your issue may be addressed there.
- Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- Consider asking first in the Gitter chat room or in a Discussion.
What version (or hash if on master) of pybind11 are you using?
2.10.4
Problem description
py::overload_cast fails to compile on AppleClang 14.0.0.14000029 (it does compile on GCC) for a member function that has both a template version, and a non-template version taking an argument.
struct Foo {
template <typename T>
void bar();
void bar(int x);
}
where
.def("bar", py::overload_cast<int>(&Foo::bar));
fails on Clang, and compiles on GCC. The equivalent static_cast compiles on both
.def("bar", static_cast<void (Foo::*) (int)>(&Foo::bar));
[ 50%] Building CXX object CMakeFiles/pybind_template_mwe.dir/main.cpp.o
pybind_template_mwe/main.cpp:14:21: error: no matching function for call to object of type 'const detail::overload_cast_impl<int>'
.def("bar", py::overload_cast<int>(&Foo::bar));
^~~~~~~~~~~~~~~~~~~~~~
include/pybind11/detail/common.h:1076:20: note: candidate template ignored: couldn't infer template argument 'Return'
constexpr auto operator()(Return (*pf)(Args...)) const noexcept -> decltype(pf) {
^
include/pybind11/detail/common.h:1081:20: note: candidate template ignored: couldn't infer template argument 'Return'
constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept
^
include/pybind11/detail/common.h:1087:20: note: candidate function template not viable: requires 2 arguments, but 1 was provided
constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept
^
1 error generated.
Reproducible example code
#include <iostream>
#include <pybind11/pybind11.h>
namespace py = pybind11;
struct Foo {
template <typename T>
void bar() { std::cout << "bar() with template" << std::endl; }
void bar(int x) { std::cout << "bar(int)" << std::endl; }
};
PYBIND11_MODULE(pybind_template_mwe, m) {
py::class_<Foo>(m, "Foo")
.def("bar", py::overload_cast<int>(&Foo::bar));
// .def("bar", static_cast<void (Foo::*) (int)>(&Foo::bar)); // this works on clang, too
}
Is this a regression? Put the last known working version here if it is.
Not a regression
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
The failure points to include/pybind11/detail/common.h around overload_cast_impl and is reproduced by the supplied main.cpp example. Start by building that example with AppleClang and GCC, then inspect the reported overload_cast_impl candidates. Done means the overload_cast form compiles on AppleClang while retaining the existing GCC behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100