Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a question continuing the post Function passed as template argument. In the provided code:

#include <iostream>

void add1(int &v)
{
  v+=1;
}

void add2(int &v)
{
  v+=2;
}

template <void (*T)(int &)>
void doOperation()
{
  int temp=0;
  T(temp);
  std::cout << "Result is " << temp << std::endl;
}

int main()
{
  doOperation<add1>();
  doOperation<add2>();
}

what about a third function which has a different parameter set layout, e.g.

double add3(double v1, double v2)
{
return v1+v2;
}

If this is not achievable using template at all, how do we pass an arbitrary function to another function? And how do we handle the parameter set with all kinds of possibilities? I know python may be able to do it by passing a tuple (kwargs**), but not sure about C/C++.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
270 views
Welcome To Ask or Share your Answers For Others

1 Answer

One form of passing a generic function to be called is a callable templated type:

#include <functional>
#include <iostream>

template<typename F>
void callFoo(F f) {
   f();
}

int main() {
   callFoo(std::bind([](int a, int b) {std::cout << a << ' ' << b;}, 5, 6));
}

callFoo takes a callable type, F, and calls it. Around this call, you can, for example, do timer work to time the function. In main, it's called with a lambda that has two parameters and the values given to those parameters bound to it. callFoo can then call it without storing the arguments. This is very similar to taking a parameter with the type std::function<void()>.

If, however, you don't want to use std::bind, you can pass in the arguments separately with a couple changes:

template<typename F, typename... Args>
void callFoo(F f, Args... args) { //ignoring perfect forwarding
    f(args...);
}

int main() {
    callFoo(/*lambda*/, 5, 6);
}

In these cases, passing void functions makes sense. Indeed, return values can be used as parameters and passed in with std::ref. If you plan on returning what the function returns, you'll have to handle the special case of the return type being void, as you can't assign to a void variable and return that. At this point, it's easier to direct you to my previous question on the matter. My use case for it turned out to be moot, but the solution works great for other uses.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...