【问题标题】:Template function for applying args to function用于将 args 应用于函数的模板函数
【发布时间】:2017-11-08 20:38:35
【问题描述】:

我试图编写一个函数(称为apply_args()),它接受一个特定的函数或函数对象以及调用该对象的参数,并使用完美转发来调用它。

例子:

auto fun = [](std::string a, std::string const& b) { return a += b; };

std::string s("world!");

// s is passing by lvalue ref,
// temporary object by rvalue ref 
s = apply_args(fun, std::string("Hello, "), s);

如何实现该功能?

【问题讨论】:

  • 你想写这个是因为你想从写它中学习,还是你想写它是因为你想拥有它?如果是第二个,你应该改用std::invoke
  • @DanielH - std::invoke 是一个不错的选择,但它是 C++17;这个问题被标记为 C++11
  • @DanielH 第一个

标签: c++ c++11 lambda perfect-forwarding


【解决方案1】:
template <typename Func, typename ...Args>
decltype(auto) apply_args(Func &&f, Args &&...args) {
    return f(std::forward<Args>(args)...);
}

【讨论】:

  • 适用于 C++14;但问题标记为 C++11;所以auto apply_args (Func &amp;&amp; f, Args &amp;&amp; ... args) -&gt; decltype( f(std::forward&lt;Args&gt;(args)...) )
【解决方案2】:

如果您接受将fun lambda 传递为+fun(将其转换为函数指针),我想您可以简单地将apply_args() 写为

template <typename R, typename ... Fts, typename ... As>
R apply_args (R(*fn)(Fts...), As && ... as)
 { return fn(std::forward<As>(as)...); }

完整示例

#include <string>
#include <iostream>
#include <functional>

template <typename R, typename ... Fts, typename ... As>
R apply_args (R(*fn)(Fts...), As && ... as)
 { return fn(std::forward<As>(as)...); }

int main ()
 {
   auto fun = [](std::string a, std::string const& b) { return a += b; };

   std::string s("world!");

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

   std::cout << s << std::endl;
 }

【讨论】:

  • 如果你使用尾随返回类型和decltype,那么你不需要指定第一个参数的类型,可以将它作为模板参数F,并且不需要用 lambda 做任何特别的事情(并且可以处理无法转换为函数指针的东西,比如带有 operator() 的对象或带有捕获的 lambda)。
  • @DanielH - 工作;很好的解决方案(比我的好)但确实不同。您应该提出它作为替代答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多