应用参数到函数的模板函数

3

我将尝试编写一个函数(称之为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 - Daniel H
@DanielH - std::invoke 是一个很好的选择,但它是 C++17 的;而这个问题标签是 C++11。 - max66
@DanielH 第一个。 - user1786089
2个回答

3
template <typename Func, typename ...Args>
decltype(auto) apply_args(Func &&f, Args &&...args) {
    return f(std::forward<Args>(args)...);
}

1
适用于C++14;但问题标记为C++11。因此,auto apply_args (Func && f, Args && ... args) -> decltype( f(std::forward<Args>(args)...) ) - max66

0
如果您同意将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;
 }

1
如果您使用尾随返回类型和 decltype,那么您不需要指定第一个参数的类型,只需将其作为模板参数 F,并且不需要对 lambda 做任何特殊处理(可以与无法转换为函数指针的对象一起使用,例如具有 operator() 或带有捕获的 lambda)。 - Daniel H
@DanielH - 做得好;这个解决方案很不错(比我的更好),但确实有所不同。您应该将其作为备选答案提出。 - max66

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接