問題タブ [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++ - 移動したオブジェクトはどのように使用できますか?
オブジェクトを移動した後、それは破壊可能でなければなりません:
しかし、objで他に何ができるでしょうか?別のオブジェクトをその中に移動できますか?
これは正確なタイプに依存しますか?(たとえば、std :: vectorは、すべてのTに対して信頼できない特定の保証を行うことができます。)すべてのタイプが、移動元のオブジェクトの破棄以外の何かをサポートする必要がありますか、それとも正気ですか?
c++ - マップの移動コンストラクター
ムーブ セマンティクスの「基本的なアイデア」は理解していると思いますが、独自のマップを実装する段階になったときに、ユース ケースを作成してムーブを説明しようとしたときに立ち止まって考え始めました。マップの中心。私が間違っている場合は修正してください。しかし、移動セマンティクスのビジネス全体がどのように機能するかを理解しているのは、不要なコピーを回避するのに役立つと思われることですか? 右?ここで、たとえばマップを取り上げます。この例の目的のために、マップが次のようにモデル化されていると仮定します。
そして、ここに問題があります:マップの移動ctorを考えようとすると、作成する必要があるすべてのリンクに新しいスペースを割り当て、それらのポインターをtmpマップのポインターと交換することを回避する方法がわかりませんオブジェクト (移動 ctor に引数として渡されます)。
とにかく、スペースを割り当てる必要がありますか?
c++ - 基本クラスmovectorの呼び出し[C++0x]
基本クラスのmovectorを呼び出す正しい方法はどれですか?
これ(MSVC2010では機能しますが、CBuilder2010では機能しません):
または(CBuilder2010では機能しますが、MSVC2010では機能しません):
または、両方とも間違っていますか?もしそうなら、正しい方法は何ですか(C ++ 0x標準で指定されているものに関して)?
注:CBuilderXEで機能させる方法がわかりません(どちらのバージョンも機能しません)。
c++ - std::moveの後のゾンビオブジェクト
C ++ 0x移動セマンティクスを使用してオブジェクトが移動された後の、オブジェクトの状態について混乱しています。私の理解では、オブジェクトが移動されても、それはまだ有効なオブジェクトですが、その内部状態が変更されているため、デストラクタが呼び出されたときにリソースの割り当てが解除されません。
しかし、私の理解が正しければ、移動したオブジェクトのデストラクタを呼び出す必要があります。
しかし、私が簡単なテストを実行するとき、それは起こりません:
この出力:
デストラクタが呼び出されるのは1回だけであることに注意してください。これは、ここでの私の理解がずれていることを示しています。デストラクタが2回呼び出されなかったのはなぜですか?何が起こったのかについての私の解釈は次のとおりです。
Foo f1
構築されます。Foo f1
に渡されwork
、右辺値を取りますf2
。- のmoveコンストラクター
Foo
が呼び出され、すべてのリソースがに移動f1
しf2
ます。 f2
これで、のデストラクタが呼び出され、すべてのリソースが解放されます。- これで、のデストラクタが呼び出されます
f1
が、すべてのリソースがに転送されたため、実際には何も実行されませんf2
。それでも、デストラクタは呼び出されます。
ただし、呼び出されるデストラクタは1つだけなので、ステップ4またはステップ5は実行されません。デストラクタからバックトレースを実行して、どこから呼び出されているかを確認しました。これは、手順5から呼び出されています。では、なぜf2
デストラクタも呼び出されないのでしょうか。
編集:さて、私はこれを変更して、実際にリソースを管理しているようにしました。(内部メモリバッファ。)それでも、デストラクタが1回だけ呼び出される場合と同じ動作が発生します。
c++ - コンストラクターを派生オブジェクトに移動する
移動コンストラクターを持つ派生オブジェクトがあり、基本オブジェクトにも移動セマンティクスがある場合、派生オブジェクト移動コンストラクターから基本オブジェクト移動コンストラクターを呼び出す適切な方法は何ですか?
最初に最も明白なことを試しました:
ただし、これは Base オブジェクトのコピー コンストラクターを呼び出すことになるようです。次にstd::move
、次のようにここで明示的に使用してみました。
これはうまくいきましたが、なぜそれが必要なのか混乱しています。std::move
右辺値参照を返すだけだと思いました。しかし、この例rval
ではすでに右辺値参照であるため、 への呼び出しは不要std::move
です。ただし、ここで使用しない場合std::move
は、コピー コンストラクターを呼び出すだけです。では、なぜ への呼び出しがstd::move
必要なのですか?
c++ - std::pair または std::tuple で移動セマンティクスを使用する
移動セマンティクスを利用したいが、可動クラスの 1 つが の一部である必要があるとしますstd::pair
。std::pair
目的は、右辺値として扱うことができ、一緒に転送できるを返す関数を作成することです。
std::pair
しかし、移動セマンティクスを認識させるために、それ自体に内部的な変更が加えられない限り、これがどのように行われるのかわかりません。
次のコードを検討してください。
問題はstd::make_pair
、コンストラクタ自体と同様に、std::pair
2 つのオブジェクトを取り、それらの内部コピーを作成しようとすることです。これにより、コピー コンストラクターの呼び出しが試行されます。しかし、私の例では、新しいペアをに移動res
し、コピーが作成されないようにしたいと考えています。std::pair
内部で次のコンストラクターが定義されていない限り、これは不可能だと思います。
しかし、少なくとも私が使用しているコンパイラ(gcc 4.3.2)ではそうではありません。私のコンパイラが単に古くなっている可能性があり、実際には新しいバージョンにはこのムーブ対応コンストラクタがあります。しかし、現時点では移動のセマンティクスに関する私の理解はやや不安定なので、ここで何かを見落としているだけなのかどうかはわかりません。それで、実際に再実装せずに、私が達成しようとしていることは可能std::pair
ですか? または、コンパイラが古くなっていますか?
c++ - コンテナ間で要素の範囲を移動する
移動セマンティクスを使用して、あるコンテナから別のコンテナに要素の範囲を移動する関数の C++ ドキュメントを見てきました。しかし、私はそのような機能を見つけていません。私は何が欠けていますか?
明示的なループをコピーして使用せずに、次のことを行うにはどうすればよいですか?
c++ - 範囲をサブ範囲に分割する
コンテナstd::vectorがあり、それぞれにx個のアイテムがあるサブ範囲に効率的に分割したいと思います。元のコンテナは必要ないため、アイテムを移動し、サブ範囲にコピーしないでください。
コピーを使用して分割を行うことができましたが、移動割り当てでそれを行う方法がわかりませんか?
編集:
いくつかの進歩...まだ完全にはありません、そして少し醜い
c++ - これはC++の「move」セマンティクスの正しい使用法ですか?
今夜、私は過去数日間に取り組んできたいくつかのコードを調べ、moveセマンティクス、特にstd::moveについて読み始めました。私が正しい道を進んでいて、愚かな仮定をしないことを確実にするためにあなたにプロに尋ねるいくつかの質問があります!
まず:
1)元々、私のコードには大きなベクトルを返す関数がありました。
「theVector」がこれと「throw-away」で一時的であるとすると、関数を次のように変更しました。
これは正しいです?このようにすることの落とし穴はありますか?
std::string
2)ある関数で、moveコンストラクターが自動的に呼び出されることを返すことに気づきました。文字列の戻り値(ありがとう、アラゴルン)にデバッグすると、明示的な移動コンストラクターと呼ばれることに気づきました。ベクトルではなく文字列クラス用のものがあるのはなぜですか?
移動セマンティクスを利用するために、この関数に変更を加える必要はありませんでした。
3)最後に、いくつかのパフォーマンステストを実行したかったのですが、std :: moveセマンティクスが原因で得られた驚くほど高速な結果ですか、それともコンパイラ(VS2010)も最適化を実行しましたか?
_getMilliseconds()
(簡潔にするために省略の実装)
結果は明らかに素晴らしいものでした。result1は、標準の割り当てで、630ミリ秒かかりました。2番目の結果は0msでした。これはこれらのことの良いパフォーマンステストですか?
これのいくつかは多くの人にとって明らかなことですが、コードをブレザーする直前にセマンティクスを理解していることを確認したいと思います。
前もって感謝します!
c++ - std :: moveを理解するのが少し難しすぎると思うのは私だけですか?
だから私はSOや他の場所で、、右辺値、左辺値広告などについて読んでいstd::move
ますstd::forward
。しかし、私はそれを理解することができないことがわかりました。私は時々修正に取り掛かりますが、これまでC++にあったポインターや参照などの基本的なことは理解していると思います。それは私ですか、それともこれらのものは重くなりすぎていますか?