Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>How about this one?</p> <pre><code>#include &lt;cstdio&gt; #include &lt;functional&gt; template &lt;typename F, typename F_ret, typename... F_args, typename G, typename G_ret, typename... G_args&gt; std::function&lt;G_ret (F_args...)&gt; composer(F f, F_ret (F::*)(F_args...) const , G g, G_ret (G::*)(G_args...) const) { // Cannot create and return a lambda. So using std::function as a lambda holder. std::function&lt;G_ret (F_args...)&gt; holder; holder = [f, g](F_args... args) { return g(f(args...)); }; return holder; } template&lt;typename F, typename G&gt; auto operator &gt;&gt; (F f, G g) -&gt; decltype(composer(f, &amp;F::operator(), g, &amp;G::operator())) { return composer(f, &amp;F::operator(), g, &amp;G::operator()); } int main(void) { auto l1 = [](int i , int j) { return i + j; }; auto l2 = [](int a) { return a*a; }; printf("%d\n", (l1 &gt;&gt; l2 &gt;&gt; l2)(2, 3)); // prints 625 return 0; } </code></pre> <p><strong>Edit:</strong></p> <p>Here is some enhanced code with support for free function pointers and member function pointers. I've some test code too. Beware of the number of virtual function calls taking place when you execute such deeply composed std::function objects. I think there is one virtual function call per operator() of a std::function object. Memory allocation and deallocation is another thing you have to keep in mind.</p> <pre><code>#include &lt;cstdio&gt; #include &lt;functional&gt; template &lt;typename F, typename F_ret, typename... F_args, typename G, typename G_ret, typename... G_args&gt; std::function&lt;G_ret (F_args...)&gt; composer(F f, F_ret (F::*)(F_args...) const , G g, G_ret (G::*)(G_args...) const) { // Cannot create and return a lambda. So using std::function as a lambda holder. std::function&lt;G_ret (F_args...)&gt; holder; holder = [f, g](F_args... args) { return g(f(args...)); }; return holder; } template&lt;typename F_ret, typename... F_args&gt; std::function&lt;F_ret (F_args...)&gt; make_function (F_ret (*f)(F_args...)) { // Not sure why this helper isn't available out of the box. return f; } template&lt;typename F, typename F_ret, typename... F_args&gt; std::function&lt;F_ret (F_args...)&gt; make_function (F_ret (F::*func)(F_args...), F &amp; obj) { // Composing a member function pointer and an object. // This one is probably doable without using a lambda. std::function&lt;F_ret (F_args...)&gt; holder; holder = [func, &amp;obj](F_args... args) { return (obj.*func)(args...); }; return holder; } template&lt;typename F, typename F_ret, typename... F_args&gt; std::function&lt;F_ret (F_args...)&gt; make_function (F_ret (F::*func)(F_args...) const, F const &amp; obj) { // Composing a const member function pointer and a const object. // This one is probably doable without using a lambda. std::function&lt;F_ret (F_args...)&gt; holder; holder = [func, &amp;obj](F_args... args) { return (obj.*func)(args...); }; return holder; } template&lt;typename F, typename G&gt; auto operator &gt;&gt; (F f, G g) -&gt; decltype(composer(f, &amp;F::operator(), g, &amp;G::operator())) { return composer(f, &amp;F::operator(), g, &amp;G::operator()); } // This one allows a free function pointer to be the second parameter template&lt;typename F, typename G_ret, typename... G_args&gt; auto operator &gt;&gt; (F f, G_ret (*g)(G_args...)) -&gt; decltype(f &gt;&gt; make_function(g)) { return f &gt;&gt; make_function(g); } // This one allows a free function pointer to be the first parameter template&lt;typename F, typename G_ret, typename... G_args&gt; auto operator &gt;&gt; (G_ret (*g)(G_args...), F f) -&gt; decltype(make_function(g) &gt;&gt; f) { return make_function(g) &gt;&gt; f; } // Not possible to have function pointers on both sides of the binary operator &gt;&gt; int increment(int i) { return i+1; } int sum(int i, int j) { return i+j; } struct math { int increment (int i) { return i+1; } int sum (int i, int j) const { return i+j; } }; int main(void) { auto l1 = [](int i , int j) { return i + j; }; auto l2 = [](int a) { return a*a; }; auto l3 = l1 &gt;&gt; l2 &gt;&gt; l2 &gt;&gt; increment; // does 11 allocs on Linux printf("%d\n", l3(2, 3)); // prints 626 printf("%d\n", (sum &gt;&gt; l2)(3, 3)); // prints 36 math m; printf("%d\n", (make_function(&amp;math::sum, m) &gt;&gt; make_function(&amp;math::increment, m))(2, 3)); // prints 6 return 0; } </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.
 

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