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

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

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

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

奇怪的是,如果我把它放在一个单独的文件中并且尝试编译,GCC会拒绝它。 我已经复查了一切,包括使用的编译器选项。

如果在函数的第一个声明中,那么这个代码就可以工作,最后一个参数具有默认值,如下所示:

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

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

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

这可以被称为:

 error("some error messsage"); error("some error messsage", false); error("some error messsage", false, true); 

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

请注意,如果您为第一个参数(从左边)提供默认值,而不为第二个参数提供默认值,则不会进行编译(按预期方式): http : //ideone.com/5hj46


§8.3.6/ 4说,

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

标准本身的例子:

 void f(int, int); void f(int, int = 7); 

第二个声明添加默认值!

另见§8.3.6/ 6。

答案可能在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 

– 例子]

读完这个之后,我发现MSVC10在编译器扩展closures的情况下接受了以下内容:

 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"); }