Function composition in C++ My aim was to create a function which behaves like the operator . in Haskell.

Here is what I made:

template &lt;typename F&gt;
auto compose(F&amp;&amp; f)
{
    return [a = std::move(f)](auto&amp;&amp;... args){
        return a(std::move(args)...);
    };
}

template &lt;typename F1, typename F2, typename... Fs&gt;
auto compose(F1&amp;&amp; f1, F2&amp;&amp; f2, Fs&amp;&amp;... fs)
{
    return compose(
        [first = std::move(f1), second = std::move(f2)]
        (auto&amp;&amp;... args){
            return second(first(std::move(args)...));
        },
        std::move(fs)...
    );
}


Possible usage:

int main()
{
const auto f = compose([](const auto a, const auto b){return a + b;},
                       [](const auto n){return n * n;},
                       [](const auto n){return n + 2;});
std::cout &lt;&lt; f(3, 2) &lt;&lt; std::endl;
// should output 27 ( (3 + 2) * (3 + 2) + 2 )
}


The full source with a few more examples may be found here.

I'm not sure whether to use std::move or std::forward. Which one is better? Any other suggestions?
You probably do want std::forward here. You're using forwarding references with your templated &amp;&amp; types, which means that they might actually be lvalues which the rest of the program expects to remain valid. std::move is basicall a promise that says "The owner is done with this object; feel free to plunder it". Obviously that's dangerous if it's false! std::forward, by contrast, will intelligently say whether something is free to plunder, based on whether it was free for plundering when passed as a parameter in the first place.

One other thing that I would suggest might be helpful is adding some sort of error detection. It would take a bit of work, but stuffing compose with a few well placed static_assert lines or similar would make a world of difference when trying to get something to build which has a few layers of composition. I'm thinking you could construct something helpful with is_invocable although that would require c++17.