参数列表中间的默认参数?

Joh*_*itb 52 c++ default-arguments

我在代码中看到了一个函数声明,如下所示

void error(char const *msg, bool showKind = true, bool exit);
Run Code Online (Sandbox Code Playgroud)

我首先想到这是一个错误,因为你不能在函数中间有默认参数,但是编译器接受了这个声明.谁看过这个吗?我正在使用GCC4.5.这是GCC扩展吗?

奇怪的是,如果我把它放在一个单独的文件中并尝试编译,GCC会拒绝它.我已经仔细检查了所有内容,包括使用的编译器选项.

Naw*_*waz 57

如果在函数的第一个声明中,最后一个参数具有默认值,那么该代码将起作用,如下所示:

//declaration
void error(char const *msg, bool showKind, bool exit = false);
Run Code Online (Sandbox Code Playgroud)

然后在同一范围内,您可以在后面的声明中为其他参数(从右侧)提供默认值,如下所示:

void error(char const *msg, bool showKind = true, bool exit); //okay

//void error(char const *msg = 0 , bool showKind, bool exit); // error
Run Code Online (Sandbox Code Playgroud)

可以称为:

error("some error messsage");
error("some error messsage", false);
error("some error messsage", false, true);
Run Code Online (Sandbox Code Playgroud)

在线演示:http://ideone.com/aFpUn

请注意,如果您为第一个参数(从左侧)提供默认值,而不为第二个参数提供默认值,则它将无法编译(如预期):http://ideone.com/5hj46


§8.3.6/ 4说,

对于非模板函数,可以在稍后的同一范围内的函数声明中添加默认参数.

标准本身的示例:

void f(int, int);
void f(int, int = 7);
Run Code Online (Sandbox Code Playgroud)

第二个声明添加默认值!

另见§8.3.6/ 6.

  • 没错,但它仍然令人困惑,因而也是不好的做法. (16认同)
  • 天哪,这是一个可怕的C++错误. (13认同)
  • 这显然是邪恶的8个隐藏的种子之一.顺便说一句,修复它并在函数调用上允许类似python的参数赋值将是有帮助的. (6认同)

Joh*_*ing 8

答案可能在8.3.6:

8.3.6默认参数

6除了类模板的成员函数之外,出现在类定义之外的成员函数定义中的缺省参数将添加到类定义中的成员函数声明提供的缺省参数集中.类模板的成员函数的默认参数应在类模板中的成员函数的初始声明中指定.

例:

class C {
void f(int i = 3);
void g(int i, int j = 99);
};
void C::f(int i = 3) // error: default argument already
{ } // specified in class scope
void C::g(int i = 88, int j) // in this translation unit,
{ } // C::g can be called with no argument
Run Code Online (Sandbox Code Playgroud)

阅读本文后,我发现MSVC10在关闭编译器扩展时接受了以下内容:

void error(char const* msg, bool showKind, bool exit = false);

void error(char const* msg, bool showKind = false, bool exit)
{
    msg;
    showKind;
    exit;
}

int main()
{
    error("hello");
}
Run Code Online (Sandbox Code Playgroud)