[解決済み] なぜ、コピーして移動するのか?
質問
私は、誰かがオブジェクトをコピーし、その後それをクラスのデータメンバに移動することに決めたコードをどこかで見かけました。私は、移動の全体的なポイントはコピーを避けることであると考えていたので、これは私を混乱させました。以下はその例です。
struct S
{
S(std::string str) : data(std::move(str))
{}
};
以下は私の質問です。
-
なぜ私たちは
str
? -
特に以下のようなことを考えると、コピーは高価になるのではないでしょうか?
std::string
? - 作者がコピー→ムーブと判断した理由は何でしょう?
- いつ自分でこれを行うべきでしょうか?
どのように解決するのですか?
質問に答える前に、あなたが誤解しているようなことが 1 つあります。C++11 での値による取得は、常にコピーを意味するわけではありません。rvalue が渡された場合、それは
移動
(実行可能な移動コンストラクタが存在する場合) となり、コピーされることはありません。また
std::string
には移動コンストラクタがあります。
C++03 と異なり、C++11 では、以下で説明する理由により、パラメータを値で受け取ることが慣用的であることがよくあります。また、以下を参照してください。 StackOverflow のこの Q&A も参照してください。 を参照してください。
へのrvalue-referenceを取らないのはなぜでしょうか?
str
?
のように、lvalueを渡すことができなくなるからです。
std::string s = "Hello";
S obj(s); // s is an lvalue, this won't compile!
もし
S
が rvalue を受け取るコンストラクタだけを持っていた場合、上記はコンパイルされないでしょう。
特に次のようなものがあると、コピーは高価になりませんか?
std::string
?
rvalueを渡すと、それは
に移動します。
になります。
str
に、そしてそれは最終的には
data
. コピーは行われない。一方,lvalueを渡した場合,そのlvalueは
コピーされる
にコピーされます。
str
に移動し、さらに
data
.
まとめると、rvaluesは2回、lvaluesは1回コピーして1回移動するということですね。
作者がコピー→ムーブと判断した理由は何でしょうか?
まず第一に、上に述べたように、最初のものは必ずしもコピーではない。そしてこれは、答えは「"」である。
なぜなら、それは効率的だからです(moves of
std::string
オブジェクトの移動は安価である)、そしてシンプルであるため
"です。
移動が安価であるという仮定の下では (ここでは SSO を無視します)、この設計の全体的な効率を考慮する場合、移動は実質的に無視することができます。そうすると、lvalue に対して 1 つのコピーがあります (lvalue 参照を
const
へのl値の参照を受け入れた場合のように)、r値のコピーはなく、(一方
const
).
これは、値で取ることは、lvalueの参照で取ることと同じであることを意味します。
const
を参照するのと同じであり、rvalueが提供される場合はより良いということです。
追伸: いくつかの文脈を提供するために、私は次のように考えています。 これはQ&A を指していると思います。
関連
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] ムーブセマンティクスとは何ですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] std::move()とは何ですか?また、どのような場合に使用するのですか?
-
[解決済み] C++11 rvalues と移動セマンティクスの混乱(return 文)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Visual Studio 2015で「非標準の構文; '&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] エラーが発生する。ISO C++は型を持たない宣言を禁じています。
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み】Enterキーを押して続行する
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件
-
[解決済み] const std::string & をパラメータとして渡す時代は終わったのでしょうか?
-
[解決済み] パラメータを正しく渡すには?