重新声明时替换函数默认参数

Function default argument replacing when redeclaration

本文关键字:替换 函数 默认 参数 新声明 声明      更新时间:2023-10-16

为什么以下代码格式正确:

void foo(int i, int j = 56);
void foo(int i = 42, int j);
int main(){  }

演示

但以下

void foo(int i = 42, int j);
void foo(int i, int j = 56);
int main(){  }

演示

格式不正确。我试图在N4296::8.3.6 [dcl.fct.default]中查找,发现的是以下示例:

class C 
{
    void f(int i = 3);
    void g(int i, int j = 99);
};
void C::f(int i = 3) { } //error
void C::g(int i = 88, int j) { // C::g can be called with no argument
}

但叮当似乎不是这样。

struct A
{
    void foo(int i = 42, int j);
};
void A::foo(int i, int j = 56){ }; //error
int main(){  }

演示

那么,这是一个实施问题吗?从形式上讲,所有这些例子都应该是可以接受的,不是吗?

[dcl.fct.default]

  1. [...]默认参数可以添加到同一作用域中函数的后续声明中。
void foo(int i, int j = 56);
void foo(int i = 42, int j);

这很好,因为第二个声明正在向第一个参数添加一个默认参数,而第一个参数以前没有。

[...]在给定的函数声明中,具有默认参数的参数后面的每个参数都应在此声明或先前声明中提供默认参数[...]

第二个

声明中的第二个参数已经有一个默认参数,尝试提供另一个参数将是一个错误。

void foo(int i = 42, int j); // error
void foo(int i, int j = 56);
这是一个错误,因为第一个声明为第一个参数

提供默认参数,而不是第二个参数,并且与第一个示例不同,没有以前的声明。

struct A
{
    void foo(int i = 42, int j); // the error should be here
};
void A::foo(int i, int j = 56){ }; // not here

由于与上述完全相同的原因,这是不正确的,j初始声明中没有默认参数,则示例中的下一行无关紧要。