1

Suppose we have two overloads of a function, where A and B are user-defined types:

void f(A &a, B *b);
void f(B *b);

We also have the corresponding overloads of a function implementing an algorithm:

void alg(A &a, B *b) {
    // ... some code calling f(a,b)
}

void alg(B *b) {
    // ... same code as alg(A &a, B *b), with f(a,b) replaced by f(b)
}

Is there a way to factor out the calls to f to avoid code duplication in this case?

AlwaysLearning
  • 7,257
  • 4
  • 33
  • 68

2 Answers2

3

A possible solution is using lambda:

template<typename T>
static function doAlg(T fct)
{
    // Common code, use fct() instead of f(a,b) or f(b)
}

void alg(A &a, B*b)
{
    doAlg([&a, b](){ f(a,b); }); // when doAlg call fct(), it will call f(a,b);
}

void alg(B*b)
{
    doAlg([b](){ f(b); }); // when doAlg call fct(), it will call f(b);
}

If you can not use feature of C++11 like lambda, just use functor or abstract class in place of lambda

Version with functor (if you can not/don't want to use lambda):

struct CallFWithAB
{
    CallFWithAB(A &a, B *b):
        _a(a), _b(b)
    {}

    A &_a;
    B *_b;

    void operator()()
    {
        f(_a,_b);
    }
}

struct CallFWithB
{
    CallFWithAB(B *b):
        _b(b)
    {}

    B *_b;

    void operator()()
    {
        f(_b);
    }
}

template<class T>
static function doAlg(T& fct)
{
    // Common code, use fct() instead of f(a,b) or f(b)
}

void alg(A &a, B*b)
{
    CallFWithAB caller(a,b);
    doAlg(caller); // when doAlg call fct(), it will call f(a,b);
}

void alg(B*b)
{
    CallFWithB caller(b);
    doAlg(caller); // when doAlg call fct(), it will call f(b);
}
Garf365
  • 3,619
  • 5
  • 29
  • 41
3

You can use perfect forwarding with variadic templates:

template <typename... Args>
void alg(Args&&... args)
{
    // ...

    f(std::forward<Args>(args)...);

    // ...
}
interjay
  • 107,303
  • 21
  • 270
  • 254
  • Very nice solution. The only reason I did not choose it is that I want to keep my parameter list for consistency with other classes implementing a similar `alg` member function. – AlwaysLearning Sep 20 '16 at 08:45