函数调用的结果能用作默认参数值吗?

6

有没有一种好的方法,可以编写带有函数调用默认参数的C/C++函数头?

我有一个带有以下函数的头文件:

int foo(int x, int y = 0);

我在一个庞大的代码库中工作,许多函数都调用了这个函数并依赖于这个默认值。现在需要将这个默认值更改为动态值,并且我正在寻找一种方法来实现:

int foo(int x, int y = bar());

其中bar()是一个根据系统参数生成默认值的函数。或者,这个函数原型看起来像:

int foo(int x, int y = baz.bar());

在头文件中,baz是属于一个未被实例化的对象的函数。


据我所知,这适用于C++而不是C(C不支持默认值)。 - Motti
8个回答

7

7

我会使用两个重载函数:

int foo(int x, int y);

int foo(int x){return foo(x,bar);}

如果允许将转发函数设置为内联,则性能损失可能很小,甚至为零。如果将其保留在非头文件中,则可能会有一些性能成本(可能很小),但是实现更加灵活,并且耦合度更低。


使用重载函数的建议很好,但是问题中的代码可以直接运行。 - Charlie

6
是的。你写的可以用。

真的吗?我从来没有想过。 - Dima
我在尝试之前就已经将其下降评分,因为显然是错误的。 - Mike F
编程 C++ 已经有 8 年了,居然不知道这个! - Justsalt
我一直在不断地发现关于C++的新事物 :-) - Lev

6
仅仅删除第一个声明中的可选参数并提供单个参数重载有什么问题吗?
int foo(int x)
{
    Bar bar = //whatever initialization
    return foo(x,bar.baz());
}

int foo(int x,int y)
{
  //whatever the implementation is right now
}

我认为这种方法比尝试使用某些动态默认值要更清晰、更灵活。

4
在标准中,第8.3.6节(默认参数),第5段,他们使用了这种方法来举例。具体来说,它指出默认参数是表达式,所以函数调用适用于它,尽管存在诸如名称查找和类型兼容性的限制。
在我的工作场所,我们使用这样的签名:
void An_object::An_object(
  const Foo &a,
  const Bar &b,
  const Strategem &s = Default_strategem()
);

允许客户端在类构造函数中覆盖行为。这对于影响翻译器性能的条件行为非常有用...


2

虽然有点离题,但我认为这种方法可能会在未来引入依赖问题。我会选择stbuton.myopenid.com的方法。


1

只要函数/对象的声明在作用域内,就可以在此上下文中完全有效地调用全局函数或引用全局对象。这可能是明智的(从设计良好的角度来看),也可能不是,但它应该能够正常工作。


0

尝试将bar()变成静态成员函数。这样,程序中任何具有此静态类作用域的部分都可以访问它。例如:

class Foo { public: static int bar(); };

然后您可以声明:

int foo(int x, int y = Foo::bar());

如果需要不同的对象,则传递对象实例即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接