如何推断变量参数后的模板参数?

Kur*_*tyn 3 c++ templates variadic c++11

我有以下模板功能:

template <typename...Args, typename Func>
void call(const char *name, Args...args, Func f)
{
        f(3);
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用它时,就像

    call("test", 1, 2, 3, [=](int i) { std::cout<< i; });
Run Code Online (Sandbox Code Playgroud)

编译器抱怨它无法推断模板参数Func.如何解决这个问题,知道args除了函数指针之外的任何类型.

eca*_*mur 8

从14.1p11开始:

函数模板的模板参数包不能跟随另一个模板参数,除非该模板参数可以从函数模板的参数类型列表中推导出来或者具有默认参数(14.8.2).

如果要将callable保留为最后一个参数,可以使用forward_as_tuple:

template <typename...Args, typename Func>
void call(const char *name, std::tuple<Args...> args, Func f)
{
        f(3);
}

call("test", std::forward_as_tuple(1, 2, 3), [=](int i) { std::cout<< i; });
Run Code Online (Sandbox Code Playgroud)

我们实际上可以通过合成tuple包含可调用的内容来做得更好:

#include <tuple>

template<typename... Args_F>
void call_impl(const char *name, std::tuple<Args_F... &&> args_f) {
   auto &&f = std::get<sizeof...(Args_F) - 1>(args_f);
   f(3);
}

template<typename...ArgsF>
void call(const char *name, ArgsF &&...args_f) {
   call_impl(name, std::tuple<ArgsF &&...>(std::forward<ArgsF>(args_f)...));
}
Run Code Online (Sandbox Code Playgroud)