@@ -2026,45 +2026,31 @@ constexpr PYBIND11_ALWAYS_INLINE Adapted adapt_member_ptr(T pmf) {
20262026PYBIND11_NAMESPACE_END (detail)
20272027
20282028// / Given a pointer to a member function, cast it to its `Derived` version.
2029- // / Forward everything else unchanged.
2030- template <typename /* Derived*/ , typename F>
2029+ // / For all other callables (lambdas, function pointers, etc.), forward unchanged.
2030+ // /
2031+ // / Two overloads cover all cases without explicit per-qualifier instantiations:
2032+ // /
2033+ // / (1) Generic fallback — disabled for member function pointers so that (2) wins
2034+ // / without any partial-ordering ambiguity.
2035+ // / (2) MFP overload — SFINAE on rebind_member_ptr::type, which exists for every
2036+ // / supported qualifier combination (const, &, &&, noexcept, ...). A single
2037+ // / template therefore covers all combinations that rebind_member_ptr handles.
2038+ template <
2039+ typename /* Derived*/ ,
2040+ typename F,
2041+ detail::enable_if_t <!std::is_member_function_pointer<detail::remove_reference_t <F>>::value,
2042+ int >
2043+ = 0 >
20312044constexpr auto method_adaptor (F &&f) -> decltype (std::forward<F>(f)) {
20322045 return std::forward<F>(f);
20332046}
20342047
2035- // One thin overload per supported member-function-pointer qualifier combination.
2036- // Specific parameter types are required so partial ordering prefers these over the F&& fallback.
2037- // The shared body (static_assert + implicit cast) lives in detail::adapt_member_ptr.
2038- // The no-qualifier overload is written out explicitly to avoid invoking the macro with an empty
2039- // argument, which triggers MSVC warning C4003.
2040- template <typename Derived, typename Return, typename Class, typename ... Args>
2041- constexpr auto method_adaptor (Return (Class::*pmf)(Args...)) -> Return (Derived::*)(Args...) {
2048+ template <typename Derived,
2049+ typename T,
2050+ typename Adapted = typename detail::rebind_member_ptr<Derived, T>::type>
2051+ constexpr Adapted method_adaptor (T pmf) {
20422052 return detail::adapt_member_ptr<Derived>(pmf);
20432053}
2044- // The qualifiers argument appears in type position, not expression position, so
2045- // parenthesizing it would produce invalid C++.
2046- // NOLINTBEGIN(bugprone-macro-parentheses)
2047- #define PYBIND11_METHOD_ADAPTOR (qualifiers ) \
2048- template <typename Derived, typename Return, typename Class, typename ... Args> \
2049- constexpr auto method_adaptor (Return (Class::*pmf)(Args...) qualifiers) \
2050- -> Return (Derived::*)(Args...) qualifiers { \
2051- return detail::adapt_member_ptr<Derived>(pmf); \
2052- }
2053- PYBIND11_METHOD_ADAPTOR (const )
2054- PYBIND11_METHOD_ADAPTOR (&)
2055- PYBIND11_METHOD_ADAPTOR (const &)
2056- PYBIND11_METHOD_ADAPTOR (&&)
2057- PYBIND11_METHOD_ADAPTOR (const &&)
2058- #ifdef __cpp_noexcept_function_type
2059- PYBIND11_METHOD_ADAPTOR (noexcept )
2060- PYBIND11_METHOD_ADAPTOR (const noexcept )
2061- PYBIND11_METHOD_ADAPTOR (& noexcept )
2062- PYBIND11_METHOD_ADAPTOR (const & noexcept )
2063- PYBIND11_METHOD_ADAPTOR (&& noexcept )
2064- PYBIND11_METHOD_ADAPTOR (const && noexcept )
2065- #endif
2066- #undef PYBIND11_METHOD_ADAPTOR
2067- // NOLINTEND(bugprone-macro-parentheses)
20682054
20692055PYBIND11_NAMESPACE_BEGIN (detail)
20702056
0 commit comments