5

我假设该函数已经有一个返回值,因此无法添加。

我想出解决这个问题的是添加额外的指针参数,默认为 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;

但这正是我想出的。我想知道是否有更好的方法来做到这一点。请注意,“whatever”已经在函数中。

4

5 回答 5

4

如果由于某种原因您需要二进制以及(大部分)源兼容性[*]:

前:

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);
}

如果您不希望函数重载(例如,如果funextern "C"接口的一部分),那么您实际上不必调用新函数fun。也可以fun2

[*] 正如 AndreyT 所指出的,您的解决方案的源代码兼容性是有限的。对旧函数的调用将正常调用新函数,但您可能对旧函数执行的其他一些操作将无法正常工作(因为您已更改其类型)。

我的代码中实际上也存在源不兼容问题。void(*foo)() = (void(*)()) fun;在添加重载之前是允许的,但之后它是模棱两可的。如果您想支持执行此操作的代码,那么这是不希望函数重载的第二个原因。

于 2012-11-08T17:37:17.207 回答
2

通常,我添加一个带有额外参数的方法,并使用前一种方法的默认值调用该方法:

//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);
于 2012-11-08T17:40:53.037 回答
2

这是一个扩展评论。正如其他人所建议的那样,您最好重载该函数以提供源代码和二进制兼容性。这样做的原因是,通过在函数签名中引入更改,您还可以更改损坏的符号名称,例如 from _Z3fundRKSt6vectorISt13randomexampleSaIS0_EEto _Z3fundRKSt6vectorISt13randomexampleSaIS0_EEPifun()这将破坏与通过其旧名称调用的所有其他对象的二进制兼容性。如果fun()它是动态链接库的一部分,它将破坏链接到它的所有现有二进制文件,因为动态链接器将不再能够解析_Z3fundRKSt6vectorISt13randomexampleSaIS0_EE符号引用。如果您使用重载函数版本,旧的损坏符号将仍然存在,并且将保留二进制兼容性。

于 2012-11-08T17:51:11.150 回答
0

正如其他人所说,这将是您的最终产品。

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;
}
于 2012-11-08T17:37:15.050 回答
-1

您可以尝试实现通用的观察者模式。这是一个喜欢:http: //sourcemaking.com/design_patterns/observer

当您想要添加更多参数时,将来会更好。如果您不能派生,那么作为参数传递也将是解决方案。

据我了解,您必须在此功能中执行此操作,否则是的,重载是一个很好的解决方案。

它不会破坏其他解决方案的二进制兼容性。

于 2012-11-08T17:35:37.300 回答