AnT*_*AnT 17
不,默认参数不是签名的一部分,也不是函数类型的一部分.
参数类型是签名的一部分.但是默认参数类型对参数类型没有影响,即默认参数类型对签名没有影响.
默认参数不会在任何地方"存储".默认参数是"语法糖",仅在程序编译期间存在(作为默认参数).如果在编译期间编译器注意到某些参数丢失,它将使用您指定的默认参数.默认参数的评估是在调用者的上下文中完成的.如果将临时对象指定为默认参数,则每次使用默认参数调用函数时都会创建单独的临时对象,并在调用表达式结束后立即销毁.
void foo(T t = T());
// A new temporary will be used as an argument every time you call it as `foo()`
foo();
// Equivalent to `foo(T())`. A temporary is created here, passed as an argument and
// destroyed afterwards, just like an explicit temporary would be
Run Code Online (Sandbox Code Playgroud)
如果将具有静态存储持续时间的现有对象指定为默认参数,则它将存储在您定义它的任何位置.
T global;
void foo(T& t = global);
// In this case you are using a global object as a default argument
// It is you who "store" it wherever you want to store it
foo();
// Equivalent to `foo(global)`
Run Code Online (Sandbox Code Playgroud)
如果声明默认参数但从未实际使用过它们,即如果每次都明确指定参数,则编译后的程序将无法获得这些参数的跟踪(这就是我称之为编译时"syntactic sugar"的原因).
PS要包含Johannes在下面的评论中所说的内容:即使默认参数(使用时)在调用时在调用者的上下文中进行评估,也不是通过"文本替换"来完成,因为可能出现在我的上面的例子.最值得注意的是,默认参数中使用的名称的名称查找是在函数声明中指定默认参数时完成的,而不是在调用者的评估点.