[英]How can I add an output parameter to a function without breaking existing code?
我假设函数已经有一个返回值,因此无法添加。
我想出来解决这个问题的方法是添加额外的指针参数,默认为nullptr。
之前:
bool fun(double a, std::vector<std::randomexample> const & b)
后:
bool fun(double a, std::vector<std::randomexample> const & b, int* extraoutput = nullptr)
并像这样使用它
if(extraoutput)
*extraoutput = whatever;
但这正是我提出的。 我想知道是否有更好的方法来做到这一点。 请注意,函数中已经存在“无论什么”。
如果由于某种原因你需要二进制以及(大部分)源兼容性[*]:
之前:
bool fun(double a, std::vector<std::randomexample> const & b) {
// do stuff
return true;
}
后:
bool fun(double a, std::vector<std::randomexample> const & b, int* extraoutput) {
// do stuff
if(extraoutput)
*extraoutput = whatever;
return true;
}
bool fun(double a, std::vector<std::randomexample> const & b) {
return fun(a, b, nullptr);
}
如果你不想重载函数(例如,如果fun
是一部分extern "C"
接口),那么你实际上并不需要调用新功能fun
。 它也可以很fun2
。
[*]正如AndreyT所指出的,您的解决方案的源兼容性是有限的。 调用你的旧函数会调用你的新函数,但是你可能用旧函数做的其他一些事情将无法正常工作(因为你已经改变了它的类型)。
实际上我的代码中也存在源代码不兼容的问题。 void(*foo)() = (void(*)()) fun;
在添加重载之前允许,但之后它是不明确的。 如果你想支持那样做的代码,那么这就是不希望函数重载的第二个原因。
通常,我使用额外参数添加一个方法,并使用前一个方法的默认值调用该方法:
//foo v1
void foo( S s ) {
... stuff with s;
};
//codeA_v1:
S s;
foo(s);
//codeB_v1
S s2;
foo(s2);
然后,我添加一个带有额外参数的方法:
void foo(S s){ foo(s, default_value_for_T); }
void foo(S s, T t){
... stuff with s and t
}
//codeA_v1 == codeA_v2
S s;
foo(s);
//codeB_v2
S s;
T t;
foo(s,t);
这是一个扩展的评论。 正如其他人所建议的那样,你最好使函数重载以提供源和二进制兼容性。 这样做的原因是通过引入函数签名的更改,您还可以更改损坏的符号名称,例如从_Z3fundRKSt6vectorISt13randomexampleSaIS0_EE
为_Z3fundRKSt6vectorISt13randomexampleSaIS0_EEPi
。 这将破坏与其旧的受损名称调用fun()
的所有其他对象的二进制兼容性。 如果fun()
是动态链接库的一部分,它将破坏链接它的所有现有二进制文件,因为动态链接器将无法再解析_Z3fundRKSt6vectorISt13randomexampleSaIS0_EE
符号引用。 如果你使用重载函数版本,旧的受损符号仍然存在,并且将保留二进制兼容性。
正如其他人所说,这将是您的最终产品。
bool fun(double a, std::vector<std::randomexample> const & b){
return fun(a,b,0);
}
bool fun(double a, std::vector<std::randomexample> const & b, int* extraoutput = 0){
// have fun!
if(extraoutput) *extraoutput = whatever;
return true;
}
您可以尝试实现genernic Observer模式。 这是一个类似的: http : //sourcemaking.com/design_patterns/observer
当您想要添加更多参数时,将来会更好。 如果你不能导出那么作为参数传递也将是解决方案。
据我所知,你必须在这个功能中做到这一点,否则是过载是一个很好的解决方案。
它不会破坏二进制兼容性,否则会破坏其他解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.