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. }