c++11lambdatemplate-function

Template function which takes lambda with variadic parameters


Educational task: want to write a function which take functional object and its arguments and call it using perfect forwarding:

auto fun = [](std::string a, std::string const& b) { return a += b; };
std::string s("world!");
s = apply(fun, std::string("Hello, "), s);

Had written the function:

template<typename T, typename ... Args>
T apply(std::function<T(Args...)>&& fun, Args&& ... args)
{
    return fun(std::forward<Args>(args)...);
}

However got error:

error: no matching function for call to ‘apply(main()::<lambda(std::__cxx11::string, const string&)>&, std::__cxx11::string, std::__cxx11::string&)’
    s = apply(fun, std::string("Hello, "), s);
                                            ^
candidate: template<class T, class ... Args> T&& apply(std::function<_Res(_ArgTypes ...)>, Args&& ...)
T apply(std::function<T(Args...)> fun, Args&& ... args)
    ^~~~~

note: template argument deduction/substitution failed:

note: ‘main()::<lambda(std::__cxx11::string, const string&)>’ is not derived from ‘std::function<_Res(_ArgTypes ...)>’

s = apply(fun, std::string("Hello, "), s);

What is wrong with syntax? How to fix?


Solution

  • Solution without std::function:

    template<typename F, typename ... Args>
    auto apply(F&& fun, Args&&... args) ->
        decltype(std::forward<F>(fun)(std::forward<Args>(args)...))
    {
        return std::forward<F>(fun)(std::forward<Args>(args)...);
    }