C ++默认参数可以用另一个参数初始化吗?

对于C ++中的默认参数,该值是否需要是一个常量,或者是否需要另一个参数?

也就是说,下面的工作可以吗?

RateLimiter(unsigned double rateInPermitsPerSecond, unsigned int maxAccumulatedPermits = rateInPermitsPerSecond); 

目前我收到一个错误:

RateLimiter.h:13:错误:'rateInPermitsPerSecond'未在此范围内声明

另一个参数不能用作默认值。 标准规定:

8.3.6默认参数

9每次调用相应参数的无参数的函数时,都会计算默认参数。 函数参数的评估顺序是未指定的。 因此,函数的参数不应该用在默认参数中,即使它们没有被评估。

并用以下示例说明:

 int f(int a, int b = a); // error: parameter a // used as default argument 

不,这样做是不行的,因为函数参数的求值没有sorting。 这也不起作用,因为标准不允许,但我想这是显而易见的。

请改用超载:

 void fun(int, int) {} void fun(int i) { fun(i, i); } 

我正在寻找一个合理的解释,为什么它不被允许

这实际上是个好问题。 原因是C ++没有规定参数评估的顺序。

那么让我们来想象一个稍微复杂一些的场景:

 int f(int a, int b = ++a); ... followed by ... int a = 1; f(a); 

C ++没有规定参数的评估顺序,记得吗?

那么b的价值应该是什么?

f(a)可以评估为:

f(1, 2)f(2, 2) ,这取决于参数的评估顺序。

因此,行为将是不确定的(甚至是无法确定的)。

此外,考虑一下当a和b是构造函数和复制操作符具有副作用的复杂对象时可能发生的情况。

这些副作用的顺序是不确定的。

你不能这样做,因为标准不允许。 但是,由于默认参数有效地定义了新的函数重载,所以可以通过显式定义这样的重载来获得所需的效果:

 void RateLimiter(unsigned int rateInPermitsPerSecond, unsigned int maxAccumulatedPermits); inline void RateLimiter(unsigned int rateInPermitsPerSecond) { return RateLimiter(rateInPermitsPerSecond,rateInPermitsPerSecond); } 

这表明,禁止这种标准是由语言(“因此……不应该…”)所暗示的半心半意。 他们只是不想经过这样一个很好的定义,就像明确的重载声明所做的一样:如果需要的话,他们可以指定默认的参数在显式提供之后被评估,并且从左到右。 这对函数调用中参数expression式的评估顺序没有指定(因为默认参数不对应于这样的expression式;它们是完全分离的,甚至不在相同的词法作用域中)的规则没有任何影响。 另一方面,如果他们(如他们所愿)不愿意这样做的话,他们本来可以说“不得”,而不需要为其他规则辩护(但也许有解释性的脚注)。

对于C ++中的默认参数,该值是否需要是常量,或者是否需要另一个参数?

参数的默认值不能是另一个参数。 但是,这并不意味着它必须是一个常数。 它可以是函数调用的返回值。

 int getNextDefaultID() { static int id = 0; return ++id; } struct Foo { Foo(int data, int id = getNextDefaultID()) : data_(data), id_(id) {} int data_; int id_; }; int main() { Foo f1(10); // Gets the next default ID. Foo f2(20, 999); // ID is specified. }