From 7da2f08a97dcbd75cb232283950bf01580f855b2 Mon Sep 17 00:00:00 2001 From: Stefano Avallone Date: Fri, 3 Mar 2023 23:38:51 +0100 Subject: [PATCH] core: (fixes #859) Avoid signature mismatch when creating bound callbacks --- src/core/model/callback.h | 46 ++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/core/model/callback.h b/src/core/model/callback.h index 662ca1f01..989ee19c3 100644 --- a/src/core/model/callback.h +++ b/src/core/model/callback.h @@ -441,6 +441,9 @@ class CallbackBase template class Callback : public CallbackBase { + template + friend class Callback; + public: Callback() { @@ -464,18 +467,17 @@ class Callback : public CallbackBase * \param [in] bargs The values of the bound arguments */ template - Callback(const CallbackBase& cb, BArgs... bargs) + Callback(const Callback& cb, BArgs... bargs) { - auto cbDerived = - static_cast*>(PeekPointer(cb.GetImpl())); + auto f = cb.DoPeekImpl()->GetFunction(); - std::function f(cbDerived->GetFunction()); - - CallbackComponentVector components(cbDerived->GetComponents()); + CallbackComponentVector components(cb.DoPeekImpl()->GetComponents()); components.insert(components.end(), {std::make_shared>(bargs)...}); m_impl = Create>( - [f, bargs...](UArgs... uargs) -> R { return f(bargs..., uargs...); }, + [f, bargs...](auto&&... uargs) -> R { + return f(bargs..., std::forward(uargs)...); + }, components); } @@ -508,7 +510,9 @@ class Callback : public CallbackBase std::make_shared>(bargs)...}); m_impl = Create>( - [f, bargs...](UArgs... uargs) -> R { return f(bargs..., uargs...); }, + [f, bargs...](auto&&... uargs) -> R { + return f(bargs..., std::forward(uargs)...); + }, components); } @@ -525,11 +529,23 @@ class Callback : public CallbackBase * The integer sequence is 0..N-1, where N is the number of arguments left unbound. */ template - auto BindImpl(std::index_sequence seq, BoundArgs... bargs) + auto BindImpl(std::index_sequence seq, BoundArgs&&... bargs) { - return Callback>...>( - *this, - bargs...); + Callback>...> cb; + + const auto f = DoPeekImpl()->GetFunction(); + + CallbackComponentVector components(DoPeekImpl()->GetComponents()); + components.insert(components.end(), + {std::make_shared>(bargs)...}); + + cb.m_impl = Create>( + [f, bargs...](auto&&... uargs) mutable { + return f(bargs..., std::forward(uargs)...); + }, + components); + + return cb; } public: @@ -541,7 +557,7 @@ class Callback : public CallbackBase * \return The bound callback */ template - auto Bind(BoundArgs... bargs) + auto Bind(BoundArgs&&... bargs) { static_assert(sizeof...(UArgs) > 0); return BindImpl(std::make_index_sequence{}, @@ -749,9 +765,9 @@ MakeNullCallback() */ template auto -MakeBoundCallback(R (*fnPtr)(Args...), BArgs... bargs) +MakeBoundCallback(R (*fnPtr)(Args...), BArgs&&... bargs) { - return Callback(fnPtr).Bind(bargs...); + return Callback(fnPtr).Bind(std::forward(bargs)...); } /**