2017-09-21 24 views
3

fooクラスに2つのカスタムコンストラクタがあるとします(例:foo::foo(bar const &)foo::foo(baz const &))。いくつかの条件に応じていずれかを呼び出すための良いスタイルとは何でしょうか。たとえば:コンストラクタの条件付き呼び出し

bar a; 
baz b; 
foo my_foo; 
if (...) { 
    my_foo = foo(a); 
} else { 
    my_foo = foo(b); 
} 

は、時間(とメモリ)の作成上の(削除)(私は考えている具体的な場合には非常に賢明ではありません)と、本質的に無駄にされているデフォルトの構築可能であることをfooを必要としますデフォルトで構築された一時オブジェクト。スコープのために、my_fooをifブロックまたはelseブロック内に宣言することはできません。

代わりに、ポインタを使用してnewで構成することもできます。これは、効率が悪い(間接、ヒープ割り当て)、潜在的に安全でない(保証ポインタがぶら下がりしていない; deleteにする必要がありますが、後者はstd::unique_ptrを使用して処理できます)。

foo my_foo = (...) ? foo(a) : foo(b); 

三項演算子は、網羅的であることが保証ので、スコープが問題ではありませんので、動作します。

は、私はそれを行うための一つの方法を発見しました。

私は三項演算子の大ファンではなく、条件子ブロックでいくつかの処理を行いたい場合があります。伝統的なif-else構文で同じことを達成するためのエレガントな方法はありますか?

+0

を使用することができます。もしあなたが本当に見た目を気にしていれば、関数やラムダで物を包むことができます。 –

+0

これは、ポインタ、ヌル可能型、または移動可能な型と、オブジェクトインスタンスを返す関数(ラムダを含む、優れた答えを参照)で行うことができます。デフォルトコンストラクタは必要ありません。 –

答えて

7

あなたはあなたのクラスは、制限を(たとえば構成可能デフォルトではない)がある場合を除き、これは主にスタイルや好みの問題であるラムダ

const foo my_foo = [&] 
    { 
      if (...) 
       return foo(a); 
      else 
       return foo(b); 
    }(); 
+0

良い考え。私は最適化(GCC 7、-O3)でコンパイルすると、これは三項演算子を持つバージョンと同じアセンブリを生成するので、ラムダへの関数呼び出しはインライン展開されることを確認しました。 – Jonas

関連する問題