繁体   English   中英

如何在不破坏现有代码的情况下向函数添加输出参数?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM