【问题标题】:Template function which takes lambda with variadic parameters模板函数接受带有可变参数的 lambda
【发布时间】:2017-11-13 04:32:28
【问题描述】:

教育任务:想要编写一个函数,该函数接受函数对象及其参数并使用完美转发调用它:

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

写过函数:

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

但出现错误:

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);

语法有什么问题?如何解决?

【问题讨论】:

  • fun 不是std::function 的实例。您可以使用apply(std::function&lt;void(std::string, std::string const&amp;)&gt;(fun), ...),或者您可以让apply 采用任意函数,而不是专门为std::function - 此时您将重新发明std::invoke
  • @IgorTandetnik std::function 不是必需的。没有它,你能提供并回答吗?
  • 就像我说的 - 看看std::invoke。你的 apply 试图做同样的事情。
  • @IgorTandetnik 对decltype(auto) 有一些问题:错误:“auto”之前的预期主表达式:decltype(auto) apply(F&& fun, Args&&... args)

标签: c++11 lambda template-function


【解决方案1】:

没有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)...);
}

【讨论】:

    猜你喜欢
    • 2015-05-12
    • 2013-05-11
    • 1970-01-01
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 2014-09-08
    相关资源
    最近更新 更多