Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Thinking about the problem some more based on the answer given I've found another way of solving the same problem:</p> <pre><code>template &lt;int N, int M, typename D&gt; struct call_or_recurse; template &lt;typename ...Types&gt; struct dispatcher { template &lt;typename F, typename ...Args&gt; static void impl(F f, const std::tuple&lt;Types...&gt;&amp; params, Args... args) { call_or_recurse&lt;sizeof...(Args), sizeof...(Types), dispatcher&lt;Types...&gt; &gt;::call(f, params, args...); } }; template &lt;int N, int M, typename D&gt; struct call_or_recurse { // recurse again template &lt;typename F, typename T, typename ...Args&gt; static void call(F f, const T&amp; t, Args... args) { D::template impl(f, t, std::get&lt;M-(N+1)&gt;(t), args...); } }; template &lt;int N, typename D&gt; struct call_or_recurse&lt;N,N,D&gt; { // do the call template &lt;typename F, typename T, typename ...Args&gt; static void call(F f, const T&amp;, Args... args) { f(args...); } }; </code></pre> <p>Which requires changing the implementation of <code>delayed_dispatch()</code> to:</p> <pre><code> void delayed_dispatch() { dispatcher&lt;Args...&gt;::impl(func, params); } </code></pre> <p>This works by recursively converting the <code>std::tuple</code> into a parameter pack in its own right. <code>call_or_recurse</code> is needed as a specialization to terminate the recursion with the real call, which just unpacks the completed parameter pack.</p> <p>I'm not sure this is in anyway a "better" solution, but it's another way of thinking about and solving it.</p> <hr> <p>As another alternative solution you can use <code>enable_if</code>, to form something arguably simpler than my previous solution:</p> <pre><code>#include &lt;iostream&gt; #include &lt;functional&gt; #include &lt;tuple&gt; void f(int a, double b, void* c) { std::cout &lt;&lt; a &lt;&lt; ":" &lt;&lt; b &lt;&lt; ":" &lt;&lt; c &lt;&lt; std::endl; } template &lt;typename ...Args&gt; struct save_it_for_later { std::tuple&lt;Args...&gt; params; void (*func)(Args...); template &lt;typename ...Actual&gt; typename std::enable_if&lt;sizeof...(Actual) != sizeof...(Args)&gt;::type delayed_dispatch(Actual&amp;&amp; ...a) { delayed_dispatch(std::forward&lt;Actual&gt;(a)..., std::get&lt;sizeof...(Actual)&gt;(params)); } void delayed_dispatch(Args ...args) { func(args...); } }; int main() { int a=666; double b = -1.234; void *c = NULL; save_it_for_later&lt;int,double,void*&gt; saved = { std::tuple&lt;int,double,void*&gt;(a,b,c), f}; saved.delayed_dispatch(); } </code></pre> <p>The first overload just takes one more argument from the tuple and puts it into a parameter pack. The second overload takes a matching parameter pack and then makes the real call, with the first overload being disabled in the one and only case where the second would be viable.</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. 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.
    3. VO
      singulars
      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