我有一个有很多参数的函数。 (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 ++技术/魔术/设计模式可以帮助它?
在实际情况中,它主要发生在边缘情况下,组合 只比继承更适合。
我认为<...>
可能会解决我的问题,但它需要我想避免的模板。
答案 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;
};
现在,您无法使用此模式来定义 f
或g
所做的事情,但这会声明他们的签名。如果您的定义与声明不符,则会收到错误。
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);
}
键入上面错误的签名,您将收到编译时错误。