私がC++でこのコンストラクターを持っているとしましょう:
A::A( std::string const& name,
std::string const& type,
std::vector<B> const& b_vec,
bool unique )
: _name(name), _type(type), _b_vec(b_vec), _unique(unique)
{ };
引数が右辺値の場合にこのコンストラクターをオーバーロードしたいと思います(そこでmoveセマンティクスを使用したい)。
A::A( std::string && name,
std::string && type,
std::vector<B> && b_vec,
bool unique )
: _name(name), _type(type), _b_vec(b_vec), _unique(unique)
{ };
上記の引数は、すべての引数が右辺値の場合は正常に機能しますが、次の例では、一部の引数のみが右辺値であると仮定します。
// create some lvalues somehow
std::string name = "stack overflow";
std::vector<B> vec = { ... }; // implementation of B's constructot is not important
// call a mixed constructor
A new_A_instance(name, "cool-website", vec, true);
'const&'は'&&'にバインドできませんが、'&&'は'const&'にバインドできるため、最初の(移動しない)コンストラクターが使用されることを理解しています。
(最初のコンストラクターの場合のように)コピーする代わりに(右辺値であるため)4つの引数のうち2つを移動できるため、これは最適ではないようです。
したがって、この特定の場合に演算子をオーバーロードすることはできますが、他の引数が右辺値であり、他の引数が左辺値である場合を簡単に想像できます。これらの各ケースでコンストラクターをオーバーロードする必要がありますか?これは、引数の数が増えるにつれて、組み合わせて非常に多くの過負荷につながります...
私は、より良い解決策があると感じています(おそらくテンプレートを使用していますが、私のテンプレートの知識は恥ずかしいほど低いです)。
注:この問題は、関数自体を移動するためにpass-by-ref関数をオーバーロードすることとは関係ありませんが、これは良い例であることがわかりました(特に、オーバーロードはそれほど違和感がないため)。また、例としてコンストラクターを使用しただけですが、オーバーロードされた関数は何でもかまいません。