From 17098eb760c5d5ecf5be56dad6e8c9906805d9d7 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Thu, 21 Sep 2023 21:15:45 -0700 Subject: [PATCH] Introduce `struct custom_deleter` to ensure the deleter is moved as desired (the lambda function only captures a reference, which can become dangling). --- include/pybind11/detail/smart_holder_poc.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/include/pybind11/detail/smart_holder_poc.h b/include/pybind11/detail/smart_holder_poc.h index 2b333b0ee..ed6f322b4 100644 --- a/include/pybind11/detail/smart_holder_poc.h +++ b/include/pybind11/detail/smart_holder_poc.h @@ -68,8 +68,6 @@ static constexpr bool type_has_shared_from_this(const std::enable_shared_from_th return true; } -struct smart_holder; - struct guarded_delete { std::weak_ptr released_ptr; // Trick to keep the smart_holder memory footprint small. std::function del_fun; // Rare case. @@ -110,10 +108,16 @@ guarded_delete make_guarded_builtin_delete(bool armed_flag) { return guarded_delete(builtin_delete_if_destructible, armed_flag); } +template +struct custom_deleter { + D deleter; + custom_deleter(D &&deleter) : deleter{std::move(deleter)} {} + void operator()(void *raw_ptr) { deleter(static_cast(raw_ptr)); } +}; + template guarded_delete make_guarded_custom_deleter(D &&uqp_del, bool armed_flag) { - return guarded_delete(std::function( - [&uqp_del](void *raw_ptr) { uqp_del(static_cast(raw_ptr)); }), + return guarded_delete(std::function(custom_deleter(std::move(uqp_del))), armed_flag); }