web-dev-qa-db-ja.com

前の引数からデフォルトの引数を設定できますか?

関数パラメーターリストの前の引数を、パラメーターリストの後の引数のデフォルト値として使用することは可能ですか?例えば、

void f( int a, int b = a, int c = b );

これが可能な場合、使用規則はありますか?

45
bpw1621

答えはノーです、できません。オーバーロードを使用して、必要な動作を得ることができます。

void f(int a, int b, int c);
inline void f(int a, int b) { f(a,b,b); }
inline void f(int a)        { f(a,a,a); }

最後の質問に関しては、Cはデフォルトパラメータをまったく許可していません。

67
Mike Seymour

いいえ、それは合法的なC++ではありません。これは、C++標準のセクション8.3.6/9で指定されています。

デフォルトの引数は、関数が呼び出されるたびに評価されます。関数の引数の評価の順序は指定されていません。したがって、関数のパラメータは、評価されない場合でも、デフォルトの引数式で使用されません。

そして:

int f(int a、int b = a); //エラー:パラメータaがデフォルトの引数として使用されます

また、C89は少なくともデフォルトのパラメータ値をサポートしていません。

31
anon

潜在的な回避策として、次のことができます。

const int defaultValue = -999; // or something similar

void f( int a, int b = defaultValue, int c = defaultValue )
{
    if (b == defaultValue) { b = a; }
    if (c == defaultValue) { c = b; }

    //...
}
5
e.James

これは不可能です

3
Andreas Brinck

いいえ、それはできません。
「ローカル変数がこのコンテキストに表示されない可能性があります」というエラーが必ず表示されます。

2
Prasoon Saurav

あなたの最初のアイデアはこのようなことをすることかもしれません:

void something(int a, int b=-1, int c=-1){
    if(b == -1)
        b = a;
    if(c == -1)
        c = b;
}

この関数は正の値でのみ機能するため、-1を使用しました。しかし、誰かが私のクラスを使用して、メソッドに-1を送信してしまうミスをした場合はどうなりますか?それでもコンパイルと実行は行われますが、結果はユーザーにとって予測できません。したがって、賢明な方法は、デフォルトの引数を削除し、代わりに次のような同じ名前のメソッドを作成することです。

void something(int a, int b, int c){
    /* Do something with a, b and c */
}

void something(int a){
    something(a, a, a);
}

void something(int a, int b){
    something(a, b, b);
}

コーディングにそれほど時間はかかりません。オートコンプリート機能を備えたプログラミングインターフェイスで誰かがそれを使用すると、3つの可能なプロトタイプが表示されます。

1
Domino

それは違法な構文なので、私はあなたがそれをすることができるとは思いません。ただし、PDF形式のC99標準を参照してください(n1136.pdf)。

ただし、変数を静的と宣言し、関数static内で使用する場合と同様に、fを使用することでこれを回避できます。

 static int global_a; 
 
/* f()を呼び出す他の場所では、事前にこれを行ってください*/
/* global_a = 4; f(); */

voidf(void){
 int a = global_a; 
 b = c = a; 
/*..。 。*/
} 

私のエラーを指摘してくれたMichael Burrに感謝します! :)

コードを再考し、そのようなものに変更する必要があるようです。

0
t0mm13b