デフォルト引き数を使用して定義された関数が、末尾の引き数が欠落している状態で呼び出されると、 デフォルト式が評価されます。 次に例を示します。
void f(int a, int b = 2, int c = 3); // declaration // ... int a = 1; f(a); // same as call f(a,2,3) f(a,10); // same as call f(a,10,3) f(a,10,20); // no default arguments
デフォルト引き数は、関数宣言に対して検査されます。そして、関数が呼び出されるときに評価されます。 デフォルトの引き数の評価の順序は、定義されていません。 デフォルト引き数式は、関数の他のパラメーターは使用できません。 次に例を示します。
int f(int q = 3, int r = q); // error
q の値は、r に代入されるときには決まっていない場合があるので、引き数 r を引き数 q の値で初期化することはできません。 上記の関数宣言を、次のように書き直すものとします。
int q=5; int f(int q = 3, int r = q); // error
関数宣言内の r の値はやはりエラーとなります。 それは、関数の外側で定義された変数 q が、 関数に対して宣言されている引き数 q によって隠されているからです。 同様に、
typedef double D; int f(int D, int z = D(5.3) ); // error
ここでは、型 D は、関数宣言内で整数の名前として解釈されます。 型 D は、引き数 D により隠されます。 したがって、D が引き数の名前であり、型ではないため、 キャスト D(5.3) が、キャストとして解釈されません。
次の例では、非静的メンバー a を初期化指定子として使用できません。 a は、クラス X のオブジェクトが構築されるまで存在しないからです。 b は、クラス X のどのオブジェクトとも無関係に作成されるので、静的メンバー b を初期化指定子として使用することができます。 デフォルト値は、クラス宣言の最後の大括弧 } の後まで分析されないので、メンバー b をデフォルト引き数として使用した後で、それを宣言することができます。
class X { int a; f(int z = a) ; // error g(int z = b) ; // valid static int b; };
関連参照