53

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

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

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

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

4

2 回答 2

60

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

//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。

于 2011-04-12T15:37:17.393 回答
9

答案可能在 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 在关闭编译器扩展的情况下接受了以下内容:

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");
}
于 2011-04-12T15:50:25.830 回答