6

我想实现这一点:

- second parameter by default set to first argument

就像是:

int foo (int a, int b = a);

但是怎么做呢?

非常感谢!

4

4 回答 4

18

这是禁止的:

8.3.6 默认参数 [dcl.fct.default]

9) 每次调用函数时都会评估默认参数。未指定函数参数的评估顺序。 因此,函数的参数不应在默认参数表达式中使用,即使它们没有被评估。在默认参数表达式之前声明的函数的参数在范围内,可以隐藏命名空间和类成员名称。[ 例子:

int a;

int f(int a , int b = a); / / error: parameter a

/ / used as default argument

typedef int I;

int g( float I , int b = I (2)); / / error: parameter I found

int h(int a , int b = sizeof (a )); / / error, parameter a used

/ / in default argument

—结束示例]

另一种方法是重载:

int foo(int a, int b);

int foo(int a)
{
   return foo(a,a);
}
于 2012-10-11T19:56:34.020 回答
3

不允许这样做的原因已经得到解决,但是@Vyktor 的另一个解决方案是使用boost::optional而不是幻数(这与创建重载相比有利有弊):

int foo(int a, boost::optional<int> b = boost::none)
{
    if(!b) b = a;
}
于 2012-10-11T20:39:06.273 回答
2

我建议按照Luchian Grigore 的建议对这个特定任务使用重载,但通常的做法是保留一些值来表示“这是默认值”。例如

int foo( int a, int b = -1)
{
    if( b == -1){
       b = a;
    }
}

使用对象(不是标量值)可以很好地实现(通过创建保留的新交付类来表示默认值),但是使用 int 你必须这样做。

请注意,您必须 100% 确定b无法获得价值-1(或任何您保留的价值)。

于 2012-10-11T20:00:41.560 回答
0

这是一个有点有趣的答案 - 但有效:

#define TWO_FROM_ONE(a) (a),(a)

f(TWO_FROM_ONE(12));

一个缺点是这将调用某些函数两次(一个已知的宏缺点):

f(TWO_FROM_ONE(sin(123 / PI)));
于 2012-10-11T20:53:25.120 回答