6

重要な結果といくつかの重要でない結果を返す関数があるとします。重要でない結果が参照によって返されるように宣言しました。

int CalculateStuff(int param1, int param2, int& result1, int& result2);

この関数を呼び出して計算を行いたいのですが、呼び出しサイトでは重要でない結果を無視したいと思います。私は次のようにそれを行うことができます:

...
int dummy1, dummy2;
int result = CalculateStuff(100, 42, dummy1, dummy2);
... // do something with the result

ダミー変数を宣言せずに同じことを行う別の方法を検討したいと思います。

int result = CalculateStuff(100, 42, *new int, *new int);

これにはメモリリーク(許容できない)がありますが、「ダミー」の名前よりも明確に(結果を無視して)私の意図を示すという利点があります。

だから、私がそれを次のように書いたらどうなるでしょう:

int result = CalculateStuff(100, 42, auto_ptr(new int).get(), auto_ptr(new int).get());

それは合法ですか?関数のコードが実行されたときに一時的な整数はまだ存在しますか?unique_ptr代わりに使用する必要がありauto_ptrますか?

(コードのリファクタリングを提案しないでください。おそらくそうしますが、最初に、このようなものがどのように機能するかを理解したいと思います)

4

6 に答える 6

4

NULLBjarne Stroustrupによると、一部のパラメーターがオプションの場合、引数を渡す必要がないときに渡すことができるように、パラメーターをポインター型にするのに理想的なケースです。

int CalculateStuff(int param1, int param2, int * result1, int * result2);

そして使用:

int result = CalculateStuff(100, 42, NULL, NULL);

他のすべての選択肢は、これほど良くはないか、少なくともこれより良くはありません。

もちろん、の実装でCalculateStuffは、パラメータがそうであるかどうかをチェックする必要がありますNULL

于 2011-10-17T12:02:24.093 に答える
4

それは合法です。auto_ptrオブジェクトは、式が終了するまで(つまり、関数呼び出し)存続します。しかし、それは地獄のように醜いです。

関数をオーバーロードするだけです。

int CalculateStuff(int param1, int param2, int& result1, int& result2);
int CalculateStuff(int param1, int param2) { 
    int r1=0, r2=0; 
    return CalculateStuff(param1, param2, r1, r2);
}
于 2011-10-17T12:00:05.103 に答える
3

これが私のアドバイスです。コードとそのセマンティクスの正しさを理解するためにSOに依頼する必要がある場合、コードは意図を明確に表現できません

dummy1最初のバージョン(とdummy2)が最も透過的で、明らかに正しいと思います。

関数を繰り返し呼び出し、オプションの結果が必要ない場合は、オーバーロードを指定できます。

int CalculateStuff(int param1, int param2, int& result1, int& result2) {}

int CalculateStuff(int param1, int param2) {
  int unwanted1, unwanted2;
  return CalculateStuff(param1, param2, unwanted1, unwanted2);
}
于 2011-10-17T12:02:13.493 に答える
3

関数を制御できる場合に推奨されるアプローチは、次のとおりです。すべての結果でstd::tuple(またはboost::tuple)を返すか、追加の変数を必要としないオーバーロードを記述します。

于 2011-10-17T12:00:50.203 に答える
3

に暗黙的(または明示的)な変換を提供するクラスを作成できますint&

struct ignored
{
   int n;
   operator int&() { return n; }
};

n = CalculateStuff(a, b, ignored(), ignored());

これをさらにテンプレートにして、constオーバーロードを追加できます。

于 2011-10-17T12:17:08.437 に答える
2

それは合法ですが、メモリをリークしないことは保証されていません 。たとえば、ここの質問3を参照してください。

オプションの出力を実装する正しくて慣用的な方法は、ポインターを渡しNULL、結果が必要ないときに渡し、ポインターNULLを書き込む前に関数でテストすることです。

于 2011-10-17T13:05:41.313 に答える