Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I find this to be the most elegant solution (and it is optimally forwarded):</p> <pre><code>#include &lt;cstddef&gt; #include &lt;tuple&gt; #include &lt;type_traits&gt; #include &lt;utility&gt; template&lt;size_t N&gt; struct Apply { template&lt;typename F, typename T, typename... A&gt; static inline auto apply(F &amp;&amp; f, T &amp;&amp; t, A &amp;&amp;... a) -&gt; decltype(Apply&lt;N-1&gt;::apply( ::std::forward&lt;F&gt;(f), ::std::forward&lt;T&gt;(t), ::std::get&lt;N-1&gt;(::std::forward&lt;T&gt;(t)), ::std::forward&lt;A&gt;(a)... )) { return Apply&lt;N-1&gt;::apply(::std::forward&lt;F&gt;(f), ::std::forward&lt;T&gt;(t), ::std::get&lt;N-1&gt;(::std::forward&lt;T&gt;(t)), ::std::forward&lt;A&gt;(a)... ); } }; template&lt;&gt; struct Apply&lt;0&gt; { template&lt;typename F, typename T, typename... A&gt; static inline auto apply(F &amp;&amp; f, T &amp;&amp;, A &amp;&amp;... a) -&gt; decltype(::std::forward&lt;F&gt;(f)(::std::forward&lt;A&gt;(a)...)) { return ::std::forward&lt;F&gt;(f)(::std::forward&lt;A&gt;(a)...); } }; template&lt;typename F, typename T&gt; inline auto apply(F &amp;&amp; f, T &amp;&amp; t) -&gt; decltype(Apply&lt; ::std::tuple_size&lt; typename ::std::decay&lt;T&gt;::type &gt;::value&gt;::apply(::std::forward&lt;F&gt;(f), ::std::forward&lt;T&gt;(t))) { return Apply&lt; ::std::tuple_size&lt; typename ::std::decay&lt;T&gt;::type &gt;::value&gt;::apply(::std::forward&lt;F&gt;(f), ::std::forward&lt;T&gt;(t)); } </code></pre> <p>Example usage:</p> <pre><code>void foo(int i, bool b); std::tuple&lt;int, bool&gt; t = make_tuple(20, false); void m() { apply(&amp;foo, t); } </code></pre> <p><s>Unfortunately GCC (4.6 at least) fails to compile this with "sorry, unimplemented: mangling overload" (which simply means that the compiler doesn't yet fully implement the C++11 spec), and since it uses variadic templates, it wont work in MSVC, so it is more or less useless. However, once there is a compiler that supports the spec, it will be the best approach IMHO. (Note: it isn't that hard to modify this so that you can work around the deficiencies in GCC, or to implement it with Boost Preprocessor, but it ruins the elegance, so this is the version I am posting.)</s></p> <p>GCC 4.7 now supports this code just fine.</p> <p>Edit: Added forward around actual function call to support rvalue reference form *this in case you are using clang (or if anybody else actually gets around to adding it).</p> <p>Edit: Added missing forward around the function object in the non-member apply function's body. Thanks to pheedbaq for pointing out that it was missing.</p> <p>Edit: And here is the C++14 version just since it is so much nicer (doesn't actually compile yet):</p> <pre><code>#include &lt;cstddef&gt; #include &lt;tuple&gt; #include &lt;type_traits&gt; #include &lt;utility&gt; template&lt;size_t N&gt; struct Apply { template&lt;typename F, typename T, typename... A&gt; static inline auto apply(F &amp;&amp; f, T &amp;&amp; t, A &amp;&amp;... a) { return Apply&lt;N-1&gt;::apply(::std::forward&lt;F&gt;(f), ::std::forward&lt;T&gt;(t), ::std::get&lt;N-1&gt;(::std::forward&lt;T&gt;(t)), ::std::forward&lt;A&gt;(a)... ); } }; template&lt;&gt; struct Apply&lt;0&gt; { template&lt;typename F, typename T, typename... A&gt; static inline auto apply(F &amp;&amp; f, T &amp;&amp;, A &amp;&amp;... a) { return ::std::forward&lt;F&gt;(f)(::std::forward&lt;A&gt;(a)...); } }; template&lt;typename F, typename T&gt; inline auto apply(F &amp;&amp; f, T &amp;&amp; t) { return Apply&lt; ::std::tuple_size&lt; ::std::decay_t&lt;T&gt; &gt;::value&gt;::apply(::std::forward&lt;F&gt;(f), ::std::forward&lt;T&gt;(t)); } </code></pre> <p>Here is a version for member functions (not tested very much!):</p> <pre><code>using std::forward; // You can change this if you like unreadable code or care hugely about namespace pollution. template&lt;size_t N&gt; struct ApplyMember { template&lt;typename C, typename F, typename T, typename... A&gt; static inline auto apply(C&amp;&amp; c, F&amp;&amp; f, T&amp;&amp; t, A&amp;&amp;... a) -&gt; decltype(ApplyMember&lt;N-1&gt;::apply(forward&lt;C&gt;(c), forward&lt;F&gt;(f), forward&lt;T&gt;(t), std::get&lt;N-1&gt;(forward&lt;T&gt;(t)), forward&lt;A&gt;(a)...)) { return ApplyMember&lt;N-1&gt;::apply(forward&lt;C&gt;(c), forward&lt;F&gt;(f), forward&lt;T&gt;(t), std::get&lt;N-1&gt;(forward&lt;T&gt;(t)), forward&lt;A&gt;(a)...); } }; template&lt;&gt; struct ApplyMember&lt;0&gt; { template&lt;typename C, typename F, typename T, typename... A&gt; static inline auto apply(C&amp;&amp; c, F&amp;&amp; f, T&amp;&amp;, A&amp;&amp;... a) -&gt; decltype((forward&lt;C&gt;(c)-&gt;*forward&lt;F&gt;(f))(forward&lt;A&gt;(a)...)) { return (forward&lt;C&gt;(c)-&gt;*forward&lt;F&gt;(f))(forward&lt;A&gt;(a)...); } }; // C is the class, F is the member function, T is the tuple. template&lt;typename C, typename F, typename T&gt; inline auto apply(C&amp;&amp; c, F&amp;&amp; f, T&amp;&amp; t) -&gt; decltype(ApplyMember&lt;std::tuple_size&lt;typename std::decay&lt;T&gt;::type&gt;::value&gt;::apply(forward&lt;C&gt;(c), forward&lt;F&gt;(f), forward&lt;T&gt;(t))) { return ApplyMember&lt;std::tuple_size&lt;typename std::decay&lt;T&gt;::type&gt;::value&gt;::apply(forward&lt;C&gt;(c), forward&lt;F&gt;(f), forward&lt;T&gt;(t)); } </code></pre> <pre><code>// Example: class MyClass { public: void foo(int i, bool b); }; MyClass mc; std::tuple&lt;int, bool&gt; t = make_tuple(20, false); void m() { apply(&amp;mc, &amp;MyClass::foo, t); } </code></pre>
    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