如何将函数名称和参数的可变参数列表传递给 C++ 中的函数?

Gab*_*les 0 c++ variadic variadic-templates parameter-pack

不是What is std::invoke in c++?的重复项 。该问题专门询问了这一唯一的功能。这个问题询问一个概念,无需该功能即可 100% 解决,并且有多种替代解决方案,其中只有一些甚至使用该功能。


在 Python 中,您可以将函数名称和参数列表传递给外部函数,该外部函数调用内部函数并将这些参数传递给它,如下所示:

在Python中将带有参数的函数传递给另一个函数?

def perform(fun, *args):
    fun(*args)

def action1(args):
    # something

def action2(args):
    # something

perform(action1)
perform(action2, p)
perform(action3, p, r)
Run Code Online (Sandbox Code Playgroud)

我如何在 C++ 中做到这一点?

Hol*_*Cat 6

像这样:

template <typename F, typename ...P>
void foo(F &&func, P &&... args)
{
    std::invoke(std::forward<F>(func), std::forward<P>(args)...);
}
Run Code Online (Sandbox Code Playgroud)

如果该函数被多次调用,则只允许使用最后一次调用std::forward。其他调用必须是 just std::invoke(func, args...)

您可以分别删除std::invoke并使用std::forward<F>(func)(std::forward<P>(args)...)and func(args...),但这样做您将失去对成员指针作为“函数”的支持。


要返回函数调用的结果,只需执行return std::invoke(...),并将返回类型设置为decltype(auto)or std::invoke_result_t<F, P...>

即使传递一个返回的函数,这也有效void


如果你想让这个 SFINAE 友好,你可以使用std::invocable

template <typename F, typename ...P>
void foo(F &&func, P &&... args) requires std::invocable<F, P...>
{
    std::invoke(std::forward<F>(func), std::forward<P>(args)...);
}
Run Code Online (Sandbox Code Playgroud)

如果该函数也是在没有 的情况下调用的forward,则添加&& std::invocable<F &, P &...>


要获得正确的异常规范,请添加noexcept(std::is_nothrow_invocable_v<F, P...>)(如果该函数也在不使用 的情况下调用forward,则还要使用 进行检查<F &, P &...>)。