Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I found a solution. Instead of trying to generate a member function to reflect a decorated method I figured out that I can generate a member funct<strong>or</strong> instead. The functor is realised as a template structure with a operator()(...). This allows me to have specialisations with correct number of arguments while retaining member function call semantics.</p> <p>Sample code :</p> <pre><code>template &lt;int Count&gt; struct apply_placeholders { }; template &lt;&gt; struct apply_placeholders&lt;1&gt; { template&lt;typename CallType, typename Self, template&lt;typename&gt;class CallPtrType&gt; static CallType apply(Self* self, CallPtrType&lt;Self&gt; callPtr) { return std::bind(std::mem_fn(callPtr), self, std::placeholders::_1); } }; template &lt;&gt; struct apply_placeholders&lt;2&gt; { template&lt;typename CallType, typename Self, template&lt;typename&gt;class CallPtrType&gt; static CallType apply(Self* self, CallPtrType&lt;Self&gt; callPtr) { return std::bind(std::mem_fn(callPtr), self, std::placeholders::_1, std::placeholders::_2); } }; template &lt;&gt; struct apply_placeholders&lt;3&gt; { template&lt;typename CallType, typename Self, template&lt;typename&gt;class CallPtrType&gt; static CallType apply(Self* self, CallPtrType&lt;Self&gt; callPtr) { return std::bind(std::mem_fn(callPtr), self, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); } }; template &lt;&gt; struct apply_placeholders&lt;4&gt; { template&lt;typename CallType, typename Self, template&lt;typename&gt;class CallPtrType&gt; static CallType apply(Self* self, CallPtrType&lt;Self&gt; callPtr) { return std::bind(std::mem_fn(callPtr), self, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); } }; template&lt;typename RetType, template&lt;typename...&gt;class FrozenArgTypes, typename... ArgTypes&gt; struct mimic_functor_impl { }; template&lt;typename RetType, typename... ArgTypes&gt; struct mimic_functor_impl&lt;RetType, type_placeholder, type_placeholder&lt;ArgTypes...&gt;&gt; { public: using CallType = std::function&lt;RetType(ArgTypes...)&gt;; template&lt;typename Self&gt; using CallPtrType = RetType(Self::*)(ArgTypes...); private: CallType mCall; public: mimic_functor_impl(CallType call) : mCall{call} { } RetType operator () (ArgTypes... args) { return mCall(args...); } template&lt;typename Self&gt; static CallType make_function(Self* self, CallPtrType&lt;Self&gt; callPtr) { // manually specialise the template method because the compiler get's lost on matching "Self::*" in CallPtrType return apply_placeholders&lt;sizeof...(ArgTypes)&gt;::template apply&lt;CallType, Self, CallPtrType&gt;(self, callPtr); } }; template&lt;typename... ArgTypes&gt; struct mimic_functor_impl&lt;void, type_placeholder, type_placeholder&lt;ArgTypes...&gt;&gt; { public: using CallType = std::function&lt;void(ArgTypes...)&gt;; template&lt;typename Self&gt; using CallPtrType = void(Self::*)(ArgTypes...); private: CallType mCall; public: mimic_functor_impl(CallType call) : mCall{call} { } void operator () (ArgTypes... args) { mCall(args...); } template&lt;typename Self&gt; static CallType make_function(Self* self, CallPtrType&lt;Self&gt; callPtr) { // manually specialise the template method because the compiler get's lost on matching "Self::*" in CallPtrType return apply_placeholders&lt;sizeof...(ArgTypes)&gt;::template apply&lt;CallType, Self, CallPtrType&gt;(self, callPtr); } }; template&lt;typename Reflect&gt; struct mimic_functor : mimic_functor_impl&lt;typename Reflect::method_type, type_placeholder, typename Reflect::method_args&gt; { private: using BaseType = mimic_functor_impl&lt;typename Reflect::method_type, type_placeholder, typename Reflect::method_args&gt;; public: mimic_functor(typename BaseType::CallType call) : BaseType(call) { } }; #define __TAG(x) x ## _tag #define RPCBIND(method_name) \ public: \ using __TAG(method_name) = reflect_method&lt;decltype(&amp;ParentType::method_name)&gt;; \ mimic_functor&lt;__TAG(method_name)&gt; method_name{mimic_functor&lt;__TAG(method_name)&gt;::make_function(dynamic_cast&lt;ParentType*&gt;( const_cast&lt;SelfType*&gt;( this ) ), &amp;ParentType::method_name)}; </code></pre> <p>The rest of the code is like in the question listing.</p> <p>The <code>apply_placeholders</code> template expands a required number of placeholders to match the count of parameters in a variadic parameter pack.</p> <p>The <code>mimic_functor_impl</code> and <code>mimic_functor</code> templates create the functor whose operator ()(...) will match the reflected methods signature. The functor, when invoked, also calls the reflected method.</p> <p>The <code>make_function</code> member template function creates a bound std::function containing the reflected method with "this" pointer.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload