Skip to content

Commit 9df27bd

Browse files
committed
Allow perfect forwarding of method args
1 parent f9f3bd7 commit 9df27bd

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

include/pybind11/pybind11.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ class cpp_function : public function {
7575
/// Construct a cpp_function from a class method (non-const)
7676
template <typename Return, typename Class, typename... Arg, typename... Extra>
7777
cpp_function(Return (Class::*f)(Arg...), const Extra&... extra) {
78-
initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(args...); },
78+
initialize([f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
7979
(Return (*) (Class *, Arg...)) nullptr, extra...);
8080
}
8181

8282
/// Construct a cpp_function from a class method (const)
8383
template <typename Return, typename Class, typename... Arg, typename... Extra>
8484
cpp_function(Return (Class::*f)(Arg...) const, const Extra&... extra) {
85-
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(args...); },
85+
initialize([f](const Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },
8686
(Return (*)(const Class *, Arg ...)) nullptr, extra...);
8787
}
8888

tests/test_methods_and_attributes.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class ExampleMandA {
2121
ExampleMandA() { print_default_created(this); }
2222
ExampleMandA(int value) : value(value) { print_created(this, value); }
2323
ExampleMandA(const ExampleMandA &e) : value(e.value) { print_copy_created(this); }
24+
ExampleMandA(std::string&&) {}
2425
ExampleMandA(ExampleMandA &&e) : value(e.value) { print_move_created(this); }
2526
~ExampleMandA() { print_destroyed(this); }
2627

@@ -43,6 +44,8 @@ class ExampleMandA {
4344
void add9(int *other) { value += *other; } // passing by pointer
4445
void add10(const int *other) { value += *other; } // passing by const pointer
4546

47+
void consume_str(std::string&&) {}
48+
4649
ExampleMandA self1() { return *this; } // return by value
4750
ExampleMandA &self2() { return *this; } // return by reference
4851
const ExampleMandA &self3() { return *this; } // return by const reference
@@ -212,6 +215,7 @@ TEST_SUBMODULE(methods_and_attributes, m) {
212215
py::class_<ExampleMandA> emna(m, "ExampleMandA");
213216
emna.def(py::init<>())
214217
.def(py::init<int>())
218+
.def(py::init<std::string&&>())
215219
.def(py::init<const ExampleMandA&>())
216220
.def("add1", &ExampleMandA::add1)
217221
.def("add2", &ExampleMandA::add2)
@@ -223,6 +227,7 @@ TEST_SUBMODULE(methods_and_attributes, m) {
223227
.def("add8", &ExampleMandA::add8)
224228
.def("add9", &ExampleMandA::add9)
225229
.def("add10", &ExampleMandA::add10)
230+
.def("consume_str", &ExampleMandA::consume_str)
226231
.def("self1", &ExampleMandA::self1)
227232
.def("self2", &ExampleMandA::self2)
228233
.def("self3", &ExampleMandA::self3)

tests/test_methods_and_attributes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ def test_methods_and_attributes():
5858
assert cstats.alive() == 0
5959
assert cstats.values() == ["32"]
6060
assert cstats.default_constructions == 1
61-
assert cstats.copy_constructions == 3
62-
assert cstats.move_constructions >= 1
61+
assert cstats.copy_constructions == 2
62+
assert cstats.move_constructions == 2
6363
assert cstats.copy_assignments == 0
6464
assert cstats.move_assignments == 0
6565

0 commit comments

Comments
 (0)