Skip to content

Commit

Permalink
fix: add missing std::forward calls (#3443)
Browse files Browse the repository at this point in the history
* fix: add missing std::forward calls

Two of the four cpp_function overloads are missing std::forward calls, which seems like a simple oversight.

* add test for #3443

* add py tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix test

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
Boris-Rasin and pre-commit-ci[bot] authored Nov 7, 2021
1 parent a61e354 commit 01f938e
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
4 changes: 2 additions & 2 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class cpp_function : public function {
template <typename Return, typename Class, typename... Arg, typename... Extra>
// 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<Arg>(args)...); },
(Return (*) (Class *, Arg...)) nullptr, extra...);
}

Expand All @@ -133,7 +133,7 @@ class cpp_function : public function {
template <typename Return, typename Class, typename... Arg, typename... Extra>
// 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<Arg>(args)...); },
(Return (*)(const Class *, Arg ...)) nullptr, extra...);
}

Expand Down
15 changes: 15 additions & 0 deletions tests/test_methods_and_attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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_<ExampleMandA> emna(m, "ExampleMandA");
Expand Down Expand Up @@ -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_<RValueRefParam>(m, "RValueRefParam")
.def(py::init<>())
.def("func1", &RValueRefParam::func1)
.def("func2", &RValueRefParam::func2)
.def("func3", &RValueRefParam::func3)
.def("func4", &RValueRefParam::func4);
}
8 changes: 8 additions & 0 deletions tests/test_methods_and_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 01f938e

Please sign in to comment.