mercredi 8 avril 2020

C++11 simplify syntax of a template function calling different specializations of the same template function

There are a couple of template functions (with identical signatures) like:

template <typename T, typename P> void f1(T t, P p);
template <typename T, typename P> void f2(T t, P p);

There are also a couple of functions with identical logic that call them with different predicates:

template <typename T> void g1(T t)
{
    f1(t, Pred1{});
    ...
    f1(t, Pred2{});
    ...
}

// same as g1 but calls f2 instead of f1
template <typename T> void g2(T t)
{
    f2(t, Pred3{});
    ...
    f2(t, Pred4{});
    ...
}

I've tried to generalize them and all I could come up with is something like:

template <typename P1, typename P2, typename FP1, typename FP2, typename T>
void g(T t, FP1 fp1, FP2 fp2, P1 p1, P2 p2)
{
    fp1(t, p1);
    ...
    fp2(t, p2);
    ...
}

template <typename T> void g1(T t)
{
    g(t, f1<T, P1>, f2<T, P2>, P1{}, P2{});
}

So it is excessively verbose, especially with real types, not toy ones as in this example. I have to pass separately each f() specialization that is called in a generalized function g(), and I have to mention each predicate twice (first, its type in f specialization, second, predicate object as a separate parameter).

If I remove P1 p1, P2 p2 arguments from g(), I still have to call it like: g<P1, P2>(t, f1<T, P1>, f1<T, P2>)

Is there a way to make it simpler and avoid repetitions?

I'm limited to C++11/14.

Aucun commentaire:

Enregistrer un commentaire