diff --git a/include/pybind11/functional.h b/include/pybind11/functional.h index b5ed4350..a99ee737 100644 --- a/include/pybind11/functional.h +++ b/include/pybind11/functional.h @@ -52,7 +52,7 @@ public: auto src = reinterpret_borrow(src_); value = [src](Args... args) -> Return { gil_scoped_acquire acq; - object retval(src(std::move(args)...)); + object retval(src(std::forward(args)...)); /* Visual studio 2015 parser issue: need parentheses around this expression */ return (retval.template cast()); }; diff --git a/tests/test_callbacks.cpp b/tests/test_callbacks.cpp index 31d4e39a..bd3dcc4d 100644 --- a/tests/test_callbacks.cpp +++ b/tests/test_callbacks.cpp @@ -74,6 +74,27 @@ struct Payload { /// Something to trigger a conversion error struct Unregistered {}; +class AbstractBase { +public: + virtual unsigned int func() = 0; +}; + +void func_accepting_func_accepting_base(std::function) { } + +struct MovableObject { + bool valid = true; + + MovableObject() = default; + MovableObject(const MovableObject &) = default; + MovableObject &operator=(const MovableObject &) = default; + MovableObject(MovableObject &&o) : valid(o.valid) { o.valid = false; } + MovableObject &operator=(MovableObject &&o) { + valid = o.valid; + o.valid = false; + return *this; + } +}; + test_initializer callbacks([](py::module &m) { m.def("test_callback1", &test_callback1); m.def("test_callback2", &test_callback2); @@ -146,4 +167,15 @@ test_initializer callbacks([](py::module &m) { m.def("test_dummy_function", &test_dummy_function); // Export the payload constructor statistics for testing purposes: m.def("payload_cstats", &ConstructorStats::get); + + m.def("func_accepting_func_accepting_base", + func_accepting_func_accepting_base); + + py::class_(m, "MovableObject"); + + m.def("callback_with_movable", [](std::function f) { + auto x = MovableObject(); + f(x); // lvalue reference shouldn't move out object + return x.valid; // must still return `true` + }); }); diff --git a/tests/test_callbacks.py b/tests/test_callbacks.py index c2668aa9..f94e7b64 100644 --- a/tests/test_callbacks.py +++ b/tests/test_callbacks.py @@ -96,3 +96,9 @@ def test_function_signatures(doc): assert doc(test_callback3) == "test_callback3(arg0: Callable[[int], int]) -> str" assert doc(test_callback4) == "test_callback4() -> Callable[[int], int]" + + +def test_movable_object(): + from pybind11_tests import callback_with_movable + + assert callback_with_movable(lambda _: None) is True