問題タブ [move-constructor]
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++ - 一時オブジェクトから構築のために呼び出されなかった ctor を移動するのはなぜですか (operator+ の結果)?
回答が得られたので、この質問を読むのを気にしないでください。少し長く、おそらく時間の価値はありません。コードにバグがあり、それが原因で move コンストラクターが呼び出されませんでした。詳細については、回答を確認してください。RVO および NRVO (名前付き戻り値の最適化) は、期待どおりに発生しない呼び出しを説明する可能性があることに注意してください。
この行で move ctor が呼び出されることを期待していますが、代わりに copy ctor が呼び出されます。
Ding クラスには、ユーザー定義の move ctor と on operator+ オーバーロードがあります。move ctor が呼び出されると予想する理由は、operator+ が一時オブジェクト (rvalue 参照) を返すため、移動の最適化が行われる可能性があるからです。
私は C++ の初心者なので、ここに書いていることはすべて間違っている可能性があります。コードは次のとおりです。
VC2010 Express および MinGW (GCC 4.6) のコンパイラ呼び出し (Win7 上) は次のとおりです。
どちらのバイナリも同じ出力を生成します (プログラムの最後に破棄する順序はありません)。
この長いテキストの後の質問を思い出してDing d3 = d1 + d2;
ください。
move ctors が呼び出されない理由については他にも質問があることは承知していますが、その答えをこのケースにマッピングすることはできません。
- この C++0x コードが move コンストラクターを呼び出さないのはなぜですか?
- このコードがコピー コンストラクターを呼び出そうとしているのはなぜですか?
- Move コンストラクターが C++0x で呼び出されない
アップデート
David Rodriguez のコメントに従って、プログラムを次のように変更しました。
次に、上記のコンパイラ呼び出しを使用してプログラムを再コンパイルし、1 つのコピー ( copy for: jajajanein
) が削除された出力を取得しました。次に、次の行を試しました。
そしてタタ!今、私は仕事でムーブ・クターを見ています!...しかし、現在別のエラーがあると思います。その new の出力にはmove-gcc.exe
、dtor 呼び出しが一覧表示されていません。
2 回目の更新
operator+
悪いものを次の(おそらく同じように悪い)コードに置き換えました。
また、デストラクタから次の行を削除したところ、プログラムが異常終了するのを防ぎました。
MSVC および を使用してコンパイルすると、移動コンストラクタが呼び出されるようになりましたg++ -std=c++0x -fno-elide-constructors
。
c++ - コンストラクターと多重継承を移動する
あらすじ
クラスが多重継承を使用している場合、ムーブ コンストラクターを安全に設計するにはどうすればよいですか?
詳細
次のシナリオを検討してください。
安全に移動構築する方法はありT
ますか?U
c++ - 移動コンストラクターではなく、このコピー コンストラクターが呼び出されるのはなぜですか?
次のコード スニペットでは、移動コンストラクターが呼び出されると予想していた場所で、コピー コンストラクターが呼び出されます。
VS11 ベータ版のデバッグ モードでは、次のように表示されます。
標準を確認したところBar
、デフォルトの移動コンストラクターを自動的に生成するためのすべての要件を満たしているようですが、オブジェクトを移動できない別の理由がない限り、それは発生しないようです。ここでは、移動およびコピー コンストラクターに関連する多くの質問を見てきましたが、この特定の問題を抱えている人はいないと思います。
ここで何が起こっているかについての指針はありますか?これは標準的な動作ですか?
c++ - C ++コンストラクターと定数メンバーポインターまたは定数メンバーを移動します。メモリリークを回避するためにそれらを無効にする方法は?
constメンバー、constポインター、およびenumクラスメンバーを持つクラスがあります。
以下のサンプルコードに関する私の質問:
- 移動コンストラクターで「other」`の列挙型クラスメンバーを適切にnuliffyする方法(それに割り当てる値は?)
- 移動コンストラクタで「other」のconstポインタを無効にして、otherのデストラクタが構築中のオブジェクトのメモリを削除しないようにし、ポインタが有効になるようにするにはどうすればよいですか?
- 他のデストラクタが呼び出されないように、moveコンストラクタの「other」の定数メンバーを無効にする方法は?
c++ - 移動コンストラクター/移動代入のすべてのメンバーを無効にする必要がありますか、それともポインターだけですか?
「他の」オブジェクトの無効化を学ぶのに本当に苦労しています。ここで移動セマンティクスに関する大きな記事全体を読んだところですが、無効化について説明されていないため、がっかりしています。
「その他」のすべてのメンバーを無効にする必要があるのか 、それとも動的に割り当てられたメモリを指しているポインタだけを無効にする必要があるのか を説明してください。
ヒープ上にない (他のオブジェクトの) メンバーを無効にする必要があるのはなぜでしょうか? 正当な理由はありますか?
emulation - C ++ 03 auto_ptrで、コンパイラが生成したcopy-ctorが呼び出されないのはなぜですか?
auto_ptr
C++03でどのように機能するかを理解しています。これはこのトリックに基づいています。このトリックは、このようなコードが記述されているときに、ユーザー定義の変換を使用して、あるオブジェクトから別のオブジェクトへのポインターを盗みますauto_int p(auto_int(new int()));
。ただし、この点に関していくつか質問があります。
- コンパイラで生成されたcopy-ctorが呼び出されないのはなぜですか?
- ユーザー定義の変換がコンパイラーで生成されたcopy-ctorよりも優先されるのはなぜですか?
- そもそもコンパイラで生成されたcopy-ctorはありますか?
- そうでない場合、どの言語規則がそれを抑制しますか?
c++ - 移動コンストラクターは、constまたはnon-constの右辺値参照を取得する必要がありますか?
いくつかの場所で、次のように与えられたコピーおよび移動コンストラクターの推奨される署名を見てきました。
ここで、copyコンストラクターはconst参照を取り、moveコンストラクターはnon-const右辺値参照を取ります。
しかし、私が見る限り、これにより、以下の場合のように、関数からconstオブジェクトを返すときにmoveセマンティクスを利用できなくなります。
これをVC11BetaでテストするとT
、moveコンストラクターではなく、のコピーコンストラクターが呼び出されます。return std::move(t);
コピーコンストラクターを使用しても、引き続き呼び出されます。
t
constなので、にバインドするべきではないので、これがどのように意味があるかがわかりますT&&
。移動コンストラクター署名での使用const T&&
は正常に機能し、理にかなっていますが、other
constであるため、メンバーをヌルアウトする必要がある場合はメンバーをヌルアウトできないという問題があります。これは、すべてのメンバーがスカラーである場合にのみ機能します。または、正しい署名を持つ移動コンストラクターがあります。
一般的なケースでmoveコンストラクターが呼び出されて、t
そもそも非定数になっていることを確認する唯一の方法のように見えますが、私はそれを行うのは好きではありません。T
パフォーマンスを向上させるために、そのフォームに反対する必要があることを知っているクライアント。
ですから、私の質問は2つあると思います。まず、moveコンストラクターはconstまたはnon-constの右辺値参照を取得する必要がありますか?そして第二に:私はこの推論の線に正しいですか?constであるものを返すのをやめるべきだと?
c++ - vector::push_back は、移動コンストラクターが提供されているにもかかわらず、コピー コンストラクターの使用を主張します。
gcc から奇妙なエラーが発生しましたが、その理由がわかりません。問題をより明確にするために、次のサンプルコードを作成しました。基本的に、誤って呼び出されないように、コピー コンストラクターとコピー代入演算子をプライベートにするクラスが定義されています。
このコードがコンパイルされることを期待していますが、gcc で失敗します。実際、gcc は「branch::branch(const branch&) is private」と不平を言っていますが、これは私が理解しているように、呼び出されるべきではありません。
main() の本体を次のように置き換えると、代入演算子が機能します。
期待どおりにコンパイルおよび実行されます。
これは gcc の正しい動作ですか? もしそうなら、上記のコードの何が問題になっていますか? どんな提案も私にとって役に立ちます。ありがとうございました!
c++ - すべてのstd::move()ベースのstd :: swap()実装はバグがありますか?
重複の可能性:
移動元のオブジェクトで何ができますか?
たとえば、次のコードを参照してください。
それは私だけですか、それともここにバグがありますか?あなたがmove
a
に入るならtmp
、それからa
無効になりませんか?
つまり、move-assignmentをa
fromb
に配置して、move-constructor呼び出しにするべきではありませんnew
か?
そうでない場合、ムーブコンストラクタとムーブ代入演算子の違いは何ですか?
c++ - C++2011の移動セマンティクスを使用したコードの最適化
重複の可能性:
誰かが私に移動セマンティクスを説明できますか?
定数サイズの数学配列の次のサンプルコードについて考えてみます。
出力を生成します:
C ++ 2011の「moveセマンティクス」と「moveコンストラクター」について聞いたことがありますが、このコードで一時的なものを回避する方法があるのではないかと思います。それは本当ですか?
可能であれば、それをどのように行うか(誰かが例を書くことができれば、移動セマンティクスで見つけたドキュメントを明確に理解できないので、それは素晴らしいことです)?