C++関数でデフォルトパラメータを最後に追加する必要があるのはなぜですか?
9 に答える
言語定義を簡素化し、コードを読みやすくするため。
void foo(int x = 2, int y);
それを呼び出してデフォルト値を利用するには、次のような構文が必要です。
foo(, 3);
それはおそらくあまりにも奇妙に感じられました。もう 1 つの方法は、引数リストで名前を指定することです。
foo(y : 3);
これはすでに何かを意味しているため、新しいシンボルを使用する必要があります。
foo(y = 3); // assign 3 to y and then pass y to foo.
ISO 委員会は、関数定義の外でパラメーター名に新しい意味を導入することに不快感を覚えたため、命名方法を検討しましたが拒否されました。
C++ の設計原理にもっと興味がある場合は、StroustrupによるThe Design and Evolution of C++を読んでください。
次の関数を定義した場合:
void foo( int a, int b = 0, int c );
関数を呼び出して a と c の値を指定し、b をデフォルトのままにするにはどうすればよいでしょうか?
foo( 10, ??, 5 );
他の一部の言語 (Python など) とは異なり、C/C++ の関数引数は、次のように名前で修飾できません。
foo( a = 10, c = 5 );
それが可能であれば、デフォルトの引数はリストのどこにでもある可能性があります。
このプロトタイプの関数があると想像してください:
void testFunction(bool a = false, bool b = true, bool c);
ここで、次のように関数を呼び出したとします。
testFunction(true, false);
どのパラメータに値を指定するつもりだったのか、コンパイラはどのように判断するのでしょうか?
ほとんどの回答が指摘しているように、デフォルトのパラメーターをパラメーターリストのどこかに配置すると、関数呼び出しの複雑さとあいまいさが増します(コンパイラーにとって、そしておそらく関数のユーザーにとってより重要なことです)。
C ++の良い点の1つは、(常に良いアイデアであるとは限らない場合でも)やりたいことを実行する方法があることです。さまざまなパラメーター位置のデフォルトの引数が必要な場合は、オーバーロードを記述して、完全にパラメーター化された関数をインラインで呼び出すだけで、ほぼ確実にこれを行うことができます。
int foo( int x, int y);
int foo( int y) {
return foo( 0, y);
}
そして、そこには次のものと同等のものがあります。
int foo( int x = 0, int y);
原則として、関数パラメーターはコンパイラーによって処理され、右から左の順序でスタックに配置されます。したがって、デフォルト値を持つすべてのパラメーターを最初に評価する必要があるのは理にかなっています。
(これは、VC++ および __stdcall 関数宣言のデフォルトになる傾向がある __cdecl に適用されます)。
これは、引数の相対位置を使用して、対応するパラメーターを見つけるためです。
タイプを使用して、オプションのパラメーターが指定されていないことを識別できた可能性があります。ただし、暗黙の変換が干渉する可能性があります。もう 1 つの問題は、引数の欠落エラーではなく、オプションの引数のドロップアウトとして解釈されるプログラミング エラーです。
任意の引数をオプションにできるようにするには、引数を識別して、プログラミング エラーがないことを確認したり、あいまいさを取り除いたりする方法が必要です。これは一部の言語では可能ですが、C++ では可能ではありません。
標準化委員会が考慮しなければならなかったもう 1 つのことは、オーバーロードされた関数、テンプレートの解決、名前の検索など、既定のパラメーターが他の機能とどのように相互作用するかということでした。これらの機能は非常に複雑で、すでに説明するのが難しい方法で相互作用します。デフォルトのパラメーターをどこにでも表示できるようにすると、複雑さが増すだけです。