【问题标题】:Default argument in the middle of parameter list?参数列表中间的默认参数?
【发布时间】:2011-08-04 00:09:31
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c++ default-arguments


    【解决方案1】:

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

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

    【讨论】:

    • 没错,但它仍然令人困惑,因此是不好的做法。
    • 你是对的。不过,您是说另一个声明(中间有参数)必须是一个定义吗?
    • 天哪,这是一个可怕的 C++ 错误功能。
    • 这显然是邪恶的八种隐藏种子之一。顺便说一句,解决这个问题并允许在函数调用时进行类似 python 的参数分配会很有帮助。
    【解决方案2】:

    答案可能在 8.3.6 中:

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

    【讨论】:

      猜你喜欢
      • 2012-09-22
      • 2012-08-29
      • 1970-01-01
      • 2019-12-14
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多