Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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;
}

As you see, some library provided the template function RpcWriteKafka. It needs the parameter about a callback function(func) and its parameters(args...).

I want to define my own function doJob, which allows me to call it like this: doJob(std::make_tuple([](int i){}, 1), RpcWriteKafka, 1);. I’m expecting that the first parameter, which is a std::tuple, could be passed to the second parameter RpcWriteKafka.

Why do I used std::tuple: How to pass a function with parameter pack to a function with parameter pack

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

For now, it can’t be compiled.

The compiler generated two errors:

  1. mismatched types 'CArgs&&' and 'int', which comes from the 1 in that tuple;
  2. the second parameter RpcWriteKafka is unresolved overloaded function type.

So how to solve the two issues? Is it possible to define such a function doJob so that I can call it easily as shown in the main above?

>Solution :

First, the first parameter type of doJob should be std::tuple<CALLBACK, CArgs...> instead of std::tuple<CALLBACK, CArgs&&...> since CArgs&&
cannot be deduced in such context.

Second, since RpcWriteKafka is a function template, you can’t pass it to doJob like this, instead, you need to wrap it with lambda, so this should work (I omit the Args&&... because it is not used)

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...); });
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading