問題タブ [move-semantics]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - STL コンテナーから要素を移動すると、そのコンテナーから要素が削除されますか?
「こんにちは!」を出力するメソッドを持つFoobar
クラスがあります。sayHello()
次のコードを書くと
出力は次のとおりです。
なぜこれが機能するのか混乱しています。fooList[0]
初手でヌルにならないの?なぜ機能myFoo2
するのですか?
Foobar
外観は次のとおりです。
c++ - 正しい移動セマンティクスの提供
現在、割り当てられたメモリへのポインターを含むオブジェクトを使用してセマンティクスを正しく移動する方法を見つけようとしています。実際のストレージへの内部生ポインタを含む大きなデータ構造があります(効率上の理由から)。ここで、移動コンストラクターと move を追加しましたoperator=()
。これらのメソッドではstd::move()
、新しい構造へのポインタを指定しています。ただし、他の構造体からのポインターをどうするかはわかりません。
これが私がやっていることの簡単な例です:
今、私が理解していることstd::move( s1 )
からs2
、安全に実行できる唯一のことは、s1
そのコンストラクターを呼び出すことです。ただし、私が見る限り、これによりs1
、デストラクタに含まれるポインタが削除され、s2
役に立たなくなります。std::move()
したがって、ポインターを ing するときにデストラクタを安全にするために何かをしなければならないと推測しています。ここで行う最も安全な方法は0
、移動したオブジェクトでに設定することdelete
です。これまでのところ、この推論は正しいですか? または、std::move()
実際にポインターを無効にして、その使用を安全にするのに十分なほどスマートですか? これまでのところ、実際のテスト スイートでクラッシュは見られませんが、move-constructor が実際に呼び出されるかどうかは確認していません。
c++ - 例外、ムーブ セマンティクス、および最適化: コンパイラの意のまま (MSVC2010)?
C++11 の機能の一部を利用するために古い例外クラス階層をアップグレードしているときに、いくつかの速度テストを行ったところ、やや苛立たしい結果が得られました。これはすべて、x64 ビット MSVC++2010 コンパイラ、最大速度の最適化 /O2 を使用して行われました。
2 つの非常に単純なstruct
は、どちらもビット単位のコピー セマンティクスです。移動代入演算子のないもの (なぜ必要なのですか?)、もう 1 つ - あり。struct
ローカル変数に割り当てられる、これらの s の新しく作成されたインスタンスを値で返す 2 つの単純なインライン関数。try/catch
また、周囲のブロックに注意してください。コードは次のとおりです。
プログラム出力:
両方のループのアセンブラー (周囲のカウンター呼び出しを表示):
try/catch
ブロックを削除すると、両方の時間は同じです。struct
しかし、それが存在する場合、コンパイラーは冗長な move operator=を使用してコードを明らかに最適化します。また、MakeFoo
時間は のサイズとそのレイアウトに依存しますが、一般に、小さなサイズの変更に依存しない時間TFoo
よりも時間が数倍長くなります。MakeBar
質問:
MSVC++ 2010 のコンパイラ固有の機能ですか (GCC を確認できますか?)。
MakeFoo
コンパイラは呼び出しが終了するまで一時的に保持する必要があるためですか?の場合は「引き裂く」ことができませんMakeBar
。ブロックなしで同様のものに対して同じ動作を期待できます
try\catch
が、より複雑なシナリオでは?
c++ - C ++ 0x:一時オブジェクトが別の一時オブジェクトと等しい場合
この例では、f()
とはg()
それぞれ一時オブジェクトを返すため、一時オブジェクトf()=g()
の式は一時オブジェクトと等しくなります。値が正しくコピーされていれば、答えは14だと思っていたでしょう。ただし、コピー代入ではなく、ムーブ代入を呼び出します。結果として、答えは14ではありません。
これは私を本当に混乱させます。から返されるオブジェクトは一時f()
的g()
なものですが、他のオブジェクトと情報を共有しています。これは、一時オブジェクトが共有情報に対してまもなくいくつかの作業を実行する可能性があることを意味します。したがって、意味的にコピー割り当てを呼び出すことが正しい動作であると思われます。
ps。私のコンパイラはg++4.720110430です
c++ - このコピー不可能なマップは合法的な c++11 ですか? GCC 4.7 と MSVS 2010 では許可されています。Clang 3.1 はそうではありません
clang でコンパイルできないコピー不可のマップを作成しました。clang は非常に標準に準拠することを意図しているため、自分のコードが合法かどうか疑問に思っていました。MSVS 2010 および GCC 4.7 は、警告やエラーなしでこのコードをコンパイルします。
完全なコードが添付されています: 問題のある行は の最後の行ですmain
。
= delete
MSVS 2010 では削除が必要
使用時のエラーメッセージclang++-mp-3.1 -std=c++0x -stdlib=libc++ MapOfMaps.cpp
は次のとおりです。
c++ - 配列への右辺値参照: 実際に発生する可能性はありますか?
次のコードを検討してください。
実際にコンパイルできるように見える唯一のバージョンはret3()
. 実際、実装を省略して宣言するだけでもコンパイルは行われますが (もちろんリンクは行われません)、配列への右辺値参照を明示的に返す方法がわかりません。これが起こらない場合、配列への右辺値参照は禁止されていないが、使用できないと結論付けることができますか?
編集:
これが機能することに気付きました:
今の楽しみは、実際の価値を理解することです...
c++ - 移動したコンテナを再利用しますか?
移動したコンテナを再利用する正しい方法は何ですか?
私がC++0x標準ドラフトで読んだものから; 移動後のオブジェクトは
「特に明記されていない限り、そのような移動元のオブジェクトは、有効であるが指定されていない状態に置かれるものとします。」
「他の方法で指定された」インスタンスは見つかりませんでした。
ver3は少し回り道で、ver1の方がはるかに好ましいと思いますが、vec3は追加の最適化を可能にしますが、一方で、簡単に間違いを引き起こす可能性があります。
私の仮定は正しいですか?
c++ - 関数から返された場合、ローカル変数のメンバー サブオブジェクトも移動されますか?
C++11 標準では、コピー省略の条件が満たされた場合 ( §12.8/31
)、実装はreturn
ed ローカル左辺値変数と関数パラメーターを最初に右辺値として扱い (移動)、オーバーロードの解決が成功しない場合は次のように処理する必要があると述べています。その後、それを左辺値 (コピー) として扱います。
§12.8 [class.copy] p32
コピー操作の省略の基準が満たされているか、ソース オブジェクトが関数パラメーターであり、コピーされるオブジェクトが左辺値によって指定されているという事実を除いて満たされる場合、コピーのコンストラクターを選択するためのオーバーロードの解決は次のとおりです。オブジェクトが rvalue によって指定されたかのように最初に実行されます。オーバーロードの解決が失敗した場合、または選択されたコンストラクターの最初のパラメーターの型がオブジェクトの型 (おそらく cv 修飾) への右辺値参照でない場合、オブジェクトを左辺値と見なしてオーバーロードの解決が再度実行されます。[注:この 2 段階のオーバーロード解決は、コピーの省略が発生するかどうかに関係なく実行する必要があります。省略が実行されない場合に呼び出されるコンストラクターを決定し、呼び出しが省略された場合でも、選択されたコンストラクターにアクセスできる必要があります。—終わりのメモ]
これにはメンバー サブオブジェクトも含まれますか? 次のスニペットでテストしました。
Ideone での実例。 また、GCC 4.7 ToT も Clang 3.1 ToT も「move ctor」を表示しないため、標準にはメンバー サブオブジェクトが含まれていないと思われます。
私は何かを見落としましたか?私のテストコードは壊れていますか? 出力がそのままになる正確な原因は何ですか?
c++ - 移動代入演算子と「if (this != &rhs)」
クラスの割り当て演算子では、通常、割り当てられているオブジェクトが呼び出し元のオブジェクトであるかどうかを確認する必要があるため、混乱を招くことはありません。
移動代入演算子にも同じことが必要ですか? 真になる状況はthis == &rhs
ありますか?
c++ - C++ はコピー代入演算子からムーブ コンストラクターを使用しますか?
次のように、ベクトルを含み、コピー代入演算子を定義する単純な構造体と、この構造体を返す関数があるとします。
私が理解しているように、コピー代入演算子を宣言したため、コンパイラは SimpleStruct のムーブ コンストラクターを自動的に生成しません。
したがって、次のGetStruct
ような関数を使用すると:
私が言ったときに、コンパイラはベクトルをコピーするのではなく、移動するのに十分スマートvec1 = other.vec1;
ですか? または、SimpleStruct がベクトルの移動を利用するために、移動コンストラクタ/代入演算子を明示的に定義する必要がありますか?