diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 124ea37e5..b8b7c7a02 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -115,7 +115,7 @@ public: template // NOLINTNEXTLINE(google-explicit-constructor) cpp_function(Return (Class::*f)(Arg...)&, const Extra&... extra) { - initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); }, + initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward(args)...); }, (Return (*) (Class *, Arg...)) nullptr, extra...); } @@ -133,7 +133,7 @@ public: template // NOLINTNEXTLINE(google-explicit-constructor) cpp_function(Return (Class::*f)(Arg...) const&, const Extra&... extra) { - initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); }, + initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(std::forward(args)...); }, (Return (*)(const Class *, Arg ...)) nullptr, extra...); } diff --git a/tests/test_methods_and_attributes.cpp b/tests/test_methods_and_attributes.cpp index 2d303a44e..9e55452de 100644 --- a/tests/test_methods_and_attributes.cpp +++ b/tests/test_methods_and_attributes.cpp @@ -159,6 +159,14 @@ struct RefQualified { int constRefQualified(int other) const & { return value + other; } }; +// Test rvalue ref param +struct RValueRefParam { + std::size_t func1(std::string&& s) { return s.size(); } + std::size_t func2(std::string&& s) const { return s.size(); } + std::size_t func3(std::string&& s) & { return s.size(); } + std::size_t func4(std::string&& s) const & { return s.size(); } +}; + TEST_SUBMODULE(methods_and_attributes, m) { // test_methods_and_attributes py::class_ emna(m, "ExampleMandA"); @@ -409,4 +417,11 @@ TEST_SUBMODULE(methods_and_attributes, m) { .def_readonly("value", &RefQualified::value) .def("refQualified", &RefQualified::refQualified) .def("constRefQualified", &RefQualified::constRefQualified); + + py::class_(m, "RValueRefParam") + .def(py::init<>()) + .def("func1", &RValueRefParam::func1) + .def("func2", &RValueRefParam::func2) + .def("func3", &RValueRefParam::func3) + .def("func4", &RValueRefParam::func4); } diff --git a/tests/test_methods_and_attributes.py b/tests/test_methods_and_attributes.py index 866b3cea1..fa026f9ed 100644 --- a/tests/test_methods_and_attributes.py +++ b/tests/test_methods_and_attributes.py @@ -515,3 +515,11 @@ def test_overload_ordering(): assert "2. (arg0: {}) -> int".format(uni_name) in str(err.value) assert "3. (arg0: {}) -> int".format(uni_name) in str(err.value) assert "4. (arg0: int) -> int" in str(err.value) + + +def test_rvalue_ref_param(): + r = m.RValueRefParam() + assert r.func1("123") == 3 + assert r.func2("1234") == 4 + assert r.func3("12345") == 5 + assert r.func4("123456") == 6