C++ templates: call whichever function matches between 2 choices

Viewed 77

How can I call the function that matches using C++ templates? For example if I have the functions a and b:

void a_impl(string, int){}
void b_impl(int, string){}

template<typename X, typename Y>
void a(X x, Y y){
  a_impl(x, y);
}

template<typename X, typename Y>
void b(X x, Y y){
  b_impl(x, y);
}

template<typename X, typename Y>
void a_or_b(X x, Y y);

How do I implement a_or_b such that it calls a(x, y) if it matches, otherwise call b(x, y)?


What I'm trying to make is a for_each function that can handle these cases:

vector<pair<string, int>> v1 = {{"one", 1}, {"two", 2}};

for_each(v1, [](string x, int y){
  cout << x << " " << y << endl;
});

vector<int> v2 = {1, 2, 3};

for_each(v2, [](int x){
  cout << x << endl;
});

So far I have it working for both tuples and single variables independently but I want the appropriate version to be selected automatically. Here is my implementation so far; unpack is apply_from_tuple from this page http://www.cppsamples.com/common-tasks/apply-tuple-to-function.html.

template<typename Range, typename Func>
void for_each_unpack(Range && range, Func && func){
  for (auto && element : range){
    using Element = decltype(element);
    unpack(std::forward<Func>(func), std::forward<Element>(element));
  }
}

template<typename Range, typename Func>
void for_each_nounpack(Range && range, Func && func){
  for (auto && element : range){
    using Element = decltype(element);
    std::forward<Func>(func)(std::forward<Element>(element));
  }
}

Edit: Got it working thanks to @jotik. I put the code on github https://github.com/csiz/for_each.

2 Answers
Related