我在代码中看到了一个函数声明,如下所示
void error(char const *msg, bool showKind = true, bool exit);
我首先想到这是一个错误,因为你不能在函数中间有默认参数,但是编译器接受了这个声明。谁看过这个吗?我正在使用GCC4.5。这是GCC扩展吗?
奇怪的是,如果我把它放在一个单独的文件中并尝试编译,GCC会拒绝它。我已经仔细检查过所有内容,包括使用的编译器选项。
答案 0 :(得分:57)
如果在函数的第一个声明中,最后一个参数具有默认值,该代码将起作用,如下所示:
//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/5hj46
§8.3.6/ 4说,
对于非模板函数,默认 可以在以后添加参数 同一个函数的声明 范围。
标准本身的例子:
void f(int, int);
void f(int, int = 7);
第二个声明添加默认值!
另见§8.3.6/ 6.
答案 1 :(得分:8)
答案可能在8.3.6:
6除了班级的成员职能 模板,a中的默认参数 成员函数定义 出现在课堂之外 定义被添加到集合中 默认参数由。提供 成员函数声明 类定义。默认参数 对于类的成员函数 模板应在 成员的初始声明 类模板中的函数。
示例:
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在关闭编译器扩展时接受了以下内容:
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");
}