将函数与具有相同参数集的另一个函数封装在一起

时间:2017-02-28 09:23:16

标签: function c++11

我有一个有很多参数的函数。 (4-7参数)

为简单起见,这是一个例子: -

class B{
    friend class C;
    int f(int param1,float param2, structA a, structB b){
         //... some code ...
    }
    //.... other functions ....
};

有时,我希望封装在具有相同签名的另一个(更公开)函数下: -

class C{
    B* b;
    public: int g(int param1,float param2, structA a, structB b){
        return b->f(param1,param2,a,b);
    }
    //.... other functions ....
};

在我看来,上面的代码是: -

  • 乏味
  • 导致一些可维护性问题
  • 人为错误

是否有任何C ++技术/魔术/设计模式可以帮助它?

在实际情况中,它主要发生在边缘情况下,组合 只比继承更适合

我认为<...>可能会解决我的问题,但它需要我想避免的模板

2 个答案:

答案 0 :(得分:1)

  

但它需要我想避免使用的模板。

在我看来,这是错误的心态。如果你有充分的理由,你应该避免使用模板,否则你应该接受它们 - 它们是C ++语言的核心功能。

使用可变参数模板,您可以按如下方式创建完美转发包装:

class C{
    B* b;
public: 

    template <typename... Ts>
    int g(Ts&&... xs){
        return b->f(std::forward<Ts>(xs)...);
    }

};

上述g 功能模板将接受任意数量的参数,并通过完美转发它们来调用b->f

(使用std::forward允许您的包装器在调用包装器时正确保留传递的表达式的值类别。简而言之,这意味着不会进行不必要的复制/移动,并且引用将是正确地通过了。)

答案 1 :(得分:1)

在公共标题中:

using f_sig = int(int param1,float param2, structA a, structB b);

class hidden;
class famous {
  hidden* pImpl
public:
  f_sig g;
};

在.cpp中:

class hidden {
  friend class famous;
  f_sig f;
};

现在,您无法使用此模式来定义 fg所做的事情,但这会声明他们的签名。如果您的定义与声明不符,则会收到错误。

int hidden::f(int param1,float param2, structA a, structB b) {
  std::cout << "f!";
}
int famous::g(int param1,float param2, structA a, structB b) {
  return pImpl->f(param1, param2, a, b);
}

键入上面错误的签名,您将收到编译时错误。