以下是根据阅读cpp referrence得出来,加上一些自己的理解。
1:并不是默认参数的右边都必须是默认参数,而是在该作用域内右边参数已经有默认值。我觉得可以理解为给一个命名空间的的所有默认参数添加了一个集合,后面的默认参数可以使用之前的默认参数集。
#include<iostream>
void f(int, int, int = 10);
void f(int, int = 6, int);
void f(int = 4, int, int);
void f(int a, int b, int c) {
std::cout << a << b << c << std::endl;
}
int main() {
f();
return 0;
}
运行结果为:
但也必须保证重载函数右边的默认实参先声明,让编译器先可以右边参数的默认实参,如果改变前两个函数顺序,将会报错:缺少形参3的默认实参。
同一定义域内也不能重定义默认参数,如果将第二个函数改为f(int,int=6,int=8)也会报错
也可用命名空间验证,注意:using命令不仅仅会承接之前的默认参数集,还会及时更新之后的默认参数集合。
#include<iostream>
namespace N1 {
void f(int, int, int = 10);
}
using N1::f;
void g1() {
f(3, 1);
//此处只能见第三个默认参数,f(3),f()等调用都会报错
}
namespace N1 {
void f(int, int = 6, int);
}
void g2() {
f(3);
//using命令及时更新了默认实参集
}
namespace N1 {
void f(int = 5, int, int);
void f(int a, int b, int c) {
std::cout << a << b << c << std::endl;
}
}
int main() {
g1();
g2();
f();
return 0;
}
运行结果为
c++规定:对于非模板函数,当在同一作用域中重声明函数时,可以向已声明的函数添加默认实参。在函数调用点,可用的默认实参是由该函数所有可见的声明中所提供的默认实参的并集。重声明不能为已有可见默认值的实参引入默认值(即使值相同)。内层作用域中的重声明不从外层作用域获得默认实参。
#include<iostream>
void f(int, int = 10);
void m() {
//调用f(3,10)
f(3);
//内层定义域不能从外层得到默认参数。
//void f(int=3,int)
void f(int, int = 8);
//调用f(3,8)
f(3);