web-dev-qa-db-ja.com

パラメータリストの中央にあるデフォルト引数?

次のようなコードで関数宣言を見つけました

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

最初のパラメーター(左から)にデフォルト値を提供し、2番目のパラメーターにデフォルト値を提供しない場合、(期待どおりに)コンパイルされないことに注意してください。 http://ideone.com/5hj46


§8.3.6/ 4は言う、

非テンプレート関数の場合、デフォルトの引数を同じスコープ内の関数の後の宣言に追加できます。

標準自体の例:

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

2番目の宣言はデフォルト値を追加します!

§8.3.6/ 6も参照してください。

57
Nawaz

答えは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");
}
8
John Dibling