分解重载函数调用

时间:2016-09-20 08:04:58

标签: c++

假设我们有一个函数的两个重载,其中AB是用户定义的类型:

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

我们还有一个实现算法的函数的相应重载:

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

在这种情况下,有没有办法将f的调用分解出来以避免代码重复?

2 个答案:

答案 0 :(得分:3)

可能的解决方案是使用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);
}

如果你不能像lambda一样使用C ++ 11的功能,只需用functor或抽象类来代替lambda

带有仿函数的版本(如果你不能/不想使用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);
}

答案 1 :(得分:3)

您可以使用可变参数模板进行完美转发:

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

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

    // ...
}