5

http://www.reddit.com/r/IAmA/comments/1nl9at/i_am_a_member_of_facebooks_hhvm_team_a_c_and_d/ccjm2qsで、Andrei Alexandrescu は次のように書いています。

右辺値を const 参照にバインドすることは、右辺値参照 Hindenburg を引き起こした小さな間違いだと思います...それは長い議論になるでしょう。右辺値を const& にバインドすることは、最初に導入されたときは意味がありましたが (テンプレートがなく、微妙な点がほとんどありませんでした)、長期的には、呼び出し先側で右辺値と左辺値を区別することが事実上不可能になりました。その結果、非常に複雑な解決策 (右辺値参照) が費用のかかる修正として必要になりました。

右辺値を const 参照にバインドするという選択がなされなかった場合、移動セマンティクスと完全転送にどのように影響するでしょうか?

4

1 に答える 1

6

この質問は非常に仮説的な質問であり、答える価値はあまりないため、触れませんでした。しかし、私は考えを変えました。以前理解できなかったこの質問に答えることに価値があります。

1 つ以上の区切り記号に基づいて文字列を文字列の配列に分割するための一般的な (C++ ではなく、一般的なコンピューター言語での) API を検討してください。これは、元の文字列の一部をコピーしないように、「文字列ビュー」または「string_refs」を元の文字列に返すのが理想的です。「文字列ビュー」または「string_ref」は、元の文字列への反復子のペアにすぎません。次のようなものです:

vector<string_ref> split(const string& str, const string& delim);

vector<string_ref>が を参照していることがわかっているstrので、この関数が右辺値にバインドするのは悪い考えです。クライアントが結果を使用するようになると、引数への参照はなくなります。参照がぶら下がります。

したがって、この関数が の右辺値引数を受け入れることを禁止するstrことは、この引数を変更する予定がない場合でも、良い考えです。

そうは言っても、この例が典型的ではないことを強く示す数十年の経験があります。ほとんどの場合、関数が引数を変更しない場合、その引数が右辺値か左辺値かは問題ではありません。

したがって、白紙の場合は、一般的なケースを最も扱いやすいものにするのが理にかなっています。右辺値は にバインドできconst X&ます。しかし、 のようなケースsplitでは、この一般的なデフォルトの動作を禁止するための構文が必要です。どうですか:

vector<string_ref> split(const string& str, const string& delim);
vector<string_ref> split(const string&& str, const string& delim) = delete;

これよりもエレガントなものを思い付くのに苦労しています。

言い換えれば、通常、20/20 後知恵の恩恵を受け、下位互換性に関する制約がないため、クリーン シートが与えられた場合、再設計によりうまくいく可能性があります。しかし、この場合、私は無失点で自分自身を仮定しており、私たちが持っているものよりも優れたデザインを思いつくのに苦労しています.

<Disclaimer> 私は偏っています。 </Disclaimer>

于 2013-11-05T01:52:36.603 に答える