diff --git a/docs/changelog.rst b/docs/changelog.rst index f99d3516a..9576a8bc2 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,7 +10,9 @@ Starting with version 1.8.0, pybind11 releases use a `semantic versioning v2.3.1 (Not yet released) ----------------------------------------------------- -* TBA +* ``py::details::overload_cast_impl`` is available in C++11 mode, can be used + like ``overload_cast`` with an additional set of parantheses. + `1581 `_. v2.3.0 (June 11, 2019) ----------------------------------------------------- @@ -105,7 +107,6 @@ v2.3.0 (June 11, 2019) `#1744 `_, `#1670 `_. - v2.2.4 (September 11, 2018) ----------------------------------------------------- diff --git a/docs/classes.rst b/docs/classes.rst index 1deec9b53..a63f6a196 100644 --- a/docs/classes.rst +++ b/docs/classes.rst @@ -422,6 +422,17 @@ on constness, the ``py::const_`` tag should be used: .def("foo_mutable", py::overload_cast(&Widget::foo)) .def("foo_const", py::overload_cast(&Widget::foo, py::const_)); +If you prefer the ``py::overload_cast`` syntax but have a C++11 compatible compiler only, +you can use ``py::detail::overload_cast_impl`` with an additional set of parentheses: + +.. code-block:: cpp + + template + using overload_cast_ = pybind11::detail::overload_cast_impl; + + py::class_(m, "Pet") + .def("set", overload_cast_()(&Pet::set), "Set the pet's age") + .def("set", overload_cast_()(&Pet::set), "Set the pet's name"); .. [#cpp14] A compiler which supports the ``-std=c++14`` flag or Visual Studio 2015 Update 2 and newer. diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index d31be9c93..7fb427abd 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -720,10 +720,6 @@ struct error_scope { /// Dummy destructor wrapper that can be used to expose classes with a private destructor struct nodelete { template void operator()(T*) { } }; -// overload_cast requires variable templates: C++14 -#if defined(PYBIND11_CPP14) -#define PYBIND11_OVERLOAD_CAST 1 - NAMESPACE_BEGIN(detail) template struct overload_cast_impl { @@ -743,19 +739,23 @@ struct overload_cast_impl { }; NAMESPACE_END(detail) +// overload_cast requires variable templates: C++14 +#if defined(PYBIND11_CPP14) +#define PYBIND11_OVERLOAD_CAST 1 /// Syntax sugar for resolving overloaded function pointers: /// - regular: static_cast(&Class::func) /// - sweet: overload_cast(&Class::func) template static constexpr detail::overload_cast_impl overload_cast = {}; // MSVC 2015 only accepts this particular initialization syntax for this variable template. +#endif /// Const member function selector for overload_cast /// - regular: static_cast(&Class::func) /// - sweet: overload_cast(&Class::func, const_) static constexpr auto const_ = std::true_type{}; -#else // no overload_cast: providing something that static_assert-fails: +#if !defined(PYBIND11_CPP14) // no overload_cast: providing something that static_assert-fails: template struct overload_cast { static_assert(detail::deferred_t::value, "pybind11::overload_cast<...> requires compiling in C++14 mode"); diff --git a/tests/test_methods_and_attributes.cpp b/tests/test_methods_and_attributes.cpp index fde152b9f..c7b82f13d 100644 --- a/tests/test_methods_and_attributes.cpp +++ b/tests/test_methods_and_attributes.cpp @@ -11,6 +11,11 @@ #include "pybind11_tests.h" #include "constructor_stats.h" +#if !defined(PYBIND11_OVERLOAD_CAST) +template +using overload_cast_ = pybind11::detail::overload_cast_impl; +#endif + class ExampleMandA { public: ExampleMandA() { print_default_created(this); } @@ -242,15 +247,16 @@ TEST_SUBMODULE(methods_and_attributes, m) { .def("overloaded_const", py::overload_cast(&ExampleMandA::overloaded, py::const_)) .def("overloaded_const", py::overload_cast(&ExampleMandA::overloaded, py::const_)) #else - .def("overloaded", static_cast(&ExampleMandA::overloaded)) - .def("overloaded", static_cast(&ExampleMandA::overloaded)) - .def("overloaded", static_cast(&ExampleMandA::overloaded)) + // Use both the traditional static_cast method and the C++11 compatible overload_cast_ + .def("overloaded", overload_cast_<>()(&ExampleMandA::overloaded)) + .def("overloaded", overload_cast_()(&ExampleMandA::overloaded)) + .def("overloaded", overload_cast_()(&ExampleMandA::overloaded)) .def("overloaded", static_cast(&ExampleMandA::overloaded)) .def("overloaded", static_cast(&ExampleMandA::overloaded)) .def("overloaded", static_cast(&ExampleMandA::overloaded)) - .def("overloaded_float", static_cast(&ExampleMandA::overloaded)) - .def("overloaded_const", static_cast(&ExampleMandA::overloaded)) - .def("overloaded_const", static_cast(&ExampleMandA::overloaded)) + .def("overloaded_float", overload_cast_()(&ExampleMandA::overloaded)) + .def("overloaded_const", overload_cast_()(&ExampleMandA::overloaded, py::const_)) + .def("overloaded_const", overload_cast_()(&ExampleMandA::overloaded, py::const_)) .def("overloaded_const", static_cast(&ExampleMandA::overloaded)) .def("overloaded_const", static_cast(&ExampleMandA::overloaded)) .def("overloaded_const", static_cast(&ExampleMandA::overloaded))