Function 用另一个具有相同参数集的函数封装一个函数
我有一个有很多参数的函数。(4-7个参数) 为简单起见,以下是一个示例:-Function 用另一个具有相同参数集的函数封装一个函数,function,c++11,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;
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++技术/魔法/设计模式来帮助它? 在实际情况中,它主要发生在边缘情况下,组合比继承更合适一点
我觉得
可能会解决我的问题,但它需要模板,我希望避免使用该模板
但它需要我想要避免的模板
在我看来,这种心态是错误的。如果你有很好的理由这样做,你应该避免模板,否则你应该接受它们——它们是C++语言的核心特性。
使用可变模板,您可以创建一个完美的转发包装器,如下所示:
class C{
B* b;
public:
template <typename... Ts>
int g(Ts&&... xs){
return b->f(std::forward<Ts>(xs)...);
}
};
C类{
B*B;
公众:
模板
INTG(Ts&…xs){
返回b->f(标准:向前(xs)…);
}
};
上面的g
函数模板将接受任意数量的参数,并通过完美地转发它们来调用b->f
(使用std::forward
允许您的包装器在调用包装器时正确保留传递的表达式的值类别。简而言之,这意味着不会进行不必要的复制/移动,并且引用将正确传递。)
但它需要我想要避免的模板
在我看来,这种心态是错误的。如果你有很好的理由这样做,你应该避免模板,否则你应该接受它们——它们是C++语言的核心特性。
使用可变模板,您可以创建一个完美的转发包装器,如下所示:
class C{
B* b;
public:
template <typename... Ts>
int g(Ts&&... xs){
return b->f(std::forward<Ts>(xs)...);
}
};
C类{
B*B;
公众:
模板
INTG(Ts&…xs){
返回b->f(标准:向前(xs)…);
}
};
上面的g
函数模板将接受任意数量的参数,并通过完美地转发它们来调用b->f
(使用std::forward
允许您的包装器在调用包装器时正确保留传递的表达式的值类别。简而言之,这意味着不会进行不必要的复制/移动,并且引用将正确传递。)
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);
}
int-hidden::f(int-param1、float-param2、结构a、结构b){
标准::cout f(参数1,参数2,a,b);
}
在上面键入错误的签名,您将得到编译时错误。在公共标题中:
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);
}
int-hidden::f(int-param1、float-param2、结构a、结构b){
标准::cout f(参数1,参数2,a,b);
}
在上面输入错误的签名,您将得到编译时错误。(悲伤的脸)使用模板,我不能将其移动到.cpp->compile time increase&其他糟糕的副作用。@javaLover:除非您的代码是大量模板化的,并且充满了编译时元编程,否则添加一些包装器模板的影响在编译时间上是不可察觉的。请澄清“其他不良副作用”。还要澄清“我无法控制我要公开哪个函数”。我无法控制我要公开哪个函数。其他不良副作用=循环依赖性(这不是什么大问题)。。。。。有时,我会为pimpl进行封装,因此在这种情况下,一切都将丢失。(对不起,我没有明确提到)…你真的需要PImpl吗?信息技术我可能错了,但对我来说,这听起来像是你不必要地试图避免模板和任何可能增加编译时间的东西。这可能是合理的,但是:您衡量过添加模板对编译时间的影响吗?如果没有,你应该,然后得出你的结论。此外,PImpl正在用运行时间换取编译时间——正如我用模板链接的页面所示,存在一些开销,我不能将其移动到.cpp->compile time increase&其他糟糕的副作用。@javaLover:除非您的代码是大量模板化的,并且充满了编译时元编程,否则添加一些包装器模板的影响在编译时间上是不可察觉的。请澄清“其他不良副作用”。还要澄清“我无法控制我要公开哪个函数”。我无法控制我要公开哪个函数。其他不良副作用=循环依赖性(这不是什么大问题)。。。。。有时,我会为pimpl进行封装,因此在这种情况下,一切都将丢失。(对不起,我没有明确提到)…你真的需要PImpl吗?信息技术我可能错了,但对我来说,这听起来像是你不必要地试图避免模板和任何可能增加编译时间的东西。这可能是合理的,但是:您衡量过添加模板对编译时间的影响吗?如果没有,你应该,然后得出你的结论。此外,PImpl以运行时间换取编译时间——正如我链接的页面中所看到的,存在一些开销。我以前从未见过这样的“使用”。这节省了大约1/3的复制,谢谢。@javaLover这只是上面的一个花哨的
typedef
。函数的typedef语法很笨拙,所以我使用using
。我以前从未见过这样的“using”。这节省了大约1/3的重复,谢谢