From eb2660b08b0f42635fcd7c4bcf032fe650935091 Mon Sep 17 00:00:00 2001 From: cyy Date: Mon, 30 Sep 2024 10:20:44 +0800 Subject: [PATCH] More perfect forward --- include/pybind11/detail/init.h | 28 ++++++++++++++-------------- include/pybind11/operators.h | 8 ++++---- include/pybind11/pybind11.h | 5 +++-- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/include/pybind11/detail/init.h b/include/pybind11/detail/init.h index 79cc930c8..5ecf0b4b0 100644 --- a/include/pybind11/detail/init.h +++ b/include/pybind11/detail/init.h @@ -201,14 +201,14 @@ void construct(value_and_holder &v_h, Alias &&result, bool) { template struct constructor { template = 0> - static void execute(Class &cl, const Extra &...extra) { + static void execute(Class &cl, Extra &&...extra) { cl.def( "__init__", [](value_and_holder &v_h, Args... args) { v_h.value_ptr() = construct_or_initialize>(std::forward(args)...); }, is_new_style_constructor(), - extra...); + std::forward(extra)...); } template < @@ -216,7 +216,7 @@ struct constructor { typename... Extra, enable_if_t, Args...>::value, int> = 0> - static void execute(Class &cl, const Extra &...extra) { + static void execute(Class &cl, Extra &&...extra) { cl.def( "__init__", [](value_and_holder &v_h, Args... args) { @@ -229,7 +229,7 @@ struct constructor { } }, is_new_style_constructor(), - extra...); + std::forward(extra)...); } template < @@ -237,7 +237,7 @@ struct constructor { typename... Extra, enable_if_t, Args...>::value, int> = 0> - static void execute(Class &cl, const Extra &...extra) { + static void execute(Class &cl, Extra &&...extra) { cl.def( "__init__", [](value_and_holder &v_h, Args... args) { @@ -245,7 +245,7 @@ struct constructor { = construct_or_initialize>(std::forward(args)...); }, is_new_style_constructor(), - extra...); + std::forward(extra)...); } }; @@ -257,7 +257,7 @@ struct alias_constructor { typename... Extra, enable_if_t, Args...>::value, int> = 0> - static void execute(Class &cl, const Extra &...extra) { + static void execute(Class &cl, Extra &&...extra) { cl.def( "__init__", [](value_and_holder &v_h, Args... args) { @@ -265,7 +265,7 @@ struct alias_constructor { = construct_or_initialize>(std::forward(args)...); }, is_new_style_constructor(), - extra...); + std::forward(extra)...); } }; @@ -290,7 +290,7 @@ struct factory { // inheriting from the C++ type) the returned value needs to either already be an alias // instance, or the alias needs to be constructible from a `Class &&` argument. template - void execute(Class &cl, const Extra &...extra) && { + void execute(Class &cl, Extra &&...extra) && { #if defined(PYBIND11_CPP14) cl.def( "__init__", @@ -306,7 +306,7 @@ struct factory { v_h, func(std::forward(args)...), Py_TYPE(v_h.inst) != v_h.type->type); }, is_new_style_constructor(), - extra...); + std::forward(extra)...); } }; @@ -334,7 +334,7 @@ struct factory { // The class factory is called when the `self` type passed to `__init__` is the direct // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype. template - void execute(Class &cl, const Extra &...extra) && { + void execute(Class &cl, Extra &&...extra) && { static_assert(Class::has_alias, "The two-argument version of `py::init()` can " "only be used if the class has an alias"); @@ -359,7 +359,7 @@ struct factory { } }, is_new_style_constructor(), - extra...); + std::forward(extra)...); } }; @@ -409,7 +409,7 @@ struct pickle_factory { pickle_factory(Get get, Set set) : get(std::forward(get)), set(std::forward(set)) {} template - void execute(Class &cl, const Extra &...extra) && { + void execute(Class &cl, Extra &&...extra) && { cl.def("__getstate__", std::move(get)); #if defined(PYBIND11_CPP14) @@ -427,7 +427,7 @@ struct pickle_factory { v_h, func(std::forward(state)), Py_TYPE(v_h.inst) != v_h.type->type); }, is_new_style_constructor(), - extra...); + std::forward(extra)...); } }; diff --git a/include/pybind11/operators.h b/include/pybind11/operators.h index 16a88ae17..92bcb9a67 100644 --- a/include/pybind11/operators.h +++ b/include/pybind11/operators.h @@ -86,20 +86,20 @@ template struct op_ { static constexpr bool op_enable_if_hook = true; template - void execute(Class &cl, const Extra &...extra) const { + void execute(Class &cl, Extra &&...extra) const { using Base = typename Class::type; using L_type = conditional_t::value, Base, L>; using R_type = conditional_t::value, Base, R>; using op = op_impl; - cl.def(op::name(), &op::execute, is_operator(), extra...); + cl.def(op::name(), &op::execute, is_operator(), std::forward(extra)...); } template - void execute_cast(Class &cl, const Extra &...extra) const { + void execute_cast(Class &cl, Extra &&...extra) const { using Base = typename Class::type; using L_type = conditional_t::value, Base, L>; using R_type = conditional_t::value, Base, R>; using op = op_impl; - cl.def(op::name(), &op::execute_cast, is_operator(), extra...); + cl.def(op::name(), &op::execute_cast, is_operator(), std::forward(extra)...); } }; diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 802eebc8f..8a652ca3f 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -110,6 +110,7 @@ public: // NOLINTNEXTLINE(google-explicit-constructor) cpp_function(std::nullptr_t) {} cpp_function(std::nullptr_t, const is_setter &) {} + cpp_function(std::nullptr_t, is_setter &&) {} /// Construct a cpp_function from a vanilla function pointer template @@ -123,9 +124,9 @@ public: typename... Extra, typename = detail::enable_if_t::value>> // NOLINTNEXTLINE(google-explicit-constructor) - cpp_function(Func &&f, const Extra &...extra) { + cpp_function(Func &&f, Extra &&...extra) { initialize( - std::forward(f), (detail::function_signature_t *) nullptr, extra...); + std::forward(f), (detail::function_signature_t *) nullptr, std::forward(extra)...); } /// Construct a cpp_function from a class method (non-const, no ref-qualifier)