如何将模板函数传递给另一个函数并应用它

How to pass a template function to another function and apply it

// I can't change this function!
template<typename Function, typename... Args>
void RpcWriteKafka(Function func, Args&&... args) {
    func(std::forward<Args>(args)...);
}

// I can change this one if necessary.
template<typename FUNC, typename... Args, typename CALLBACK, typename... CArgs>
void doJob(std::tuple<CALLBACK, CArgs&&...> tp, FUNC func, Args&&... args) {
    // SetValues(std::forward<Args>(args)...);
    std::apply(func, tp);
}

int main() {
    doJob(std::make_tuple([](int i){}, 1), RpcWriteKafka, 1);

    return 0;
}

如您所见,一些库提供了模板函数RpcWriteKafka。它需要有关回调函数的参数(func)及其参数(args...).

我想定义我自己的函数 doJob,它允许我这样调用它:doJob(std::make_tuple([](int i){}, 1), RpcWriteKafka, 1);。我希望第一个参数 std::tuple 可以传递给第二个参数 RpcWriteKafka.

为什么我用了std::tuple

暂时无法编译。

编译器产生了两个错误:

  1. mismatched types 'CArgs&&' and 'int',来自那个元组中的1
  2. 第二个参数RpcWriteKafkaunresolved overloaded function type.

那么如何解决这两个问题呢?是否可以定义这样一个函数 doJob 以便我可以像上面 main 所示那样轻松调用它?

首先,doJob的第一个参数类型应该是std::tuple<CALLBACK, CArgs...>而不是std::tuple<CALLBACK, CArgs&&...>,因为CArgs&& 在这种情况下无法推断。

其次,由于RpcWriteKafka是一个函数模板,你不能像这样将它传给doJob,相反,你需要包装它使用 lambda,所以这应该可以工作(我省略了 Args&&... 因为它没有被使用)

template<typename CALLBACK, typename... CArgs, typename FUNC>
void doJob(std::tuple<CALLBACK, CArgs...>&& tp, FUNC func) {
  std::apply(func, tp);
}

int main() {
  doJob(std::make_tuple([](int i){}, 1), 
    [](auto... args) { RpcWriteKafka(args...); });
}