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

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


§8.3.6/4は言う、

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

標準自体からの例:

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

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

§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 に答える