問題タブ [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++ - この右辺値呼び出しがあいまいなのはなぜですか?
この右辺値呼び出しがあいまいなのはなぜですか? 私は AA と AA& を持つことができ、コンパイラは を使用することを認識しますAA&
。しかし、3 番目のオプションを追加すると、エラーが発生します。明らかに AA&& は、int の int のような他のものよりも優れたオーバーロードであり、long よりも優れています。なぜこれがあいまいなのですか?3 つのオーバーロードすべてを保持し、どれが必要かを明確にする方法はありますか? (型キャスト(AA&&)
はそれを行いません)。
c++ - クラス内のメソッドに対する `= delete` の正しい使用
次のスニペットは、それ以外の方法で生成されたクラスのメソッドとコンストラクターをすべて定義解除するのに正しいですか?
これにより、すべてのデフォルトのコンパイラ実装が削除され、デストラクタだけが残りますよね? それがなければ、クラスは(ほとんど)使用できないと思いますが、削除することもできますよね?
Picture&
move-assignの戻り値の型はoperator=(Picture&&)
正しいですか? Picture&&
戻り値の型について書いた場合、違いはありますか?
c++ - RValue 参照 (&&) の戻り値が役立つ場合はありますか?
関数が RValue Reference を返さなければならない理由はありますか? テクニック、トリック、イディオム、パターン?
私は一般的に参照を返すことの危険性を認識していますが、とにかくそれを行うこともありますよね? T& T::operator=(T)
は慣用的な例の 1 つにすぎません。しかし、どうT&& func(...)
ですか?それを行うことで得られる一般的な場所はありますか? クライアントコードだけと比べて、ライブラリや API コードを書くときはおそらく違いますか?
c++ - あるベクトルから別のベクトルへのunique_ptrsの移動
それらのソートされていないベクトルに格納されているunique_ptrを、ポインターのソートされたベクトルを含む別のベクトルに移動したいと思います。
確かにunique_ptrを移動しても、最初のベクトルの要素は自動的に消去されませんか?これどうやってするの?
私がやりたいことの例:
意図が明確であることを願っています。
更新:私のアルゴリズムでは、インプレースソートが許可されていません。今日誰かが気分がいいなら(私は尋ねていません、私の質問については上記を参照してください)、この状況のためにそれを自由に実装して見せてください。私は本当に「移動による並べ替え」が必要です。そして、なぜ引っ越しがそれほど高価になるのか、私にはよくわかりません。
c++ - 5のルールを実際に実装するにはどうすればよいですか?
一番下のUPDATE
q1:かなり重いリソースを管理するクラスに 5 のルールをどのように実装しますか? その使用法を大幅に簡素化して美しくするために、値によって渡す必要がありますか? それとも、ルールの 5 つの項目すべてが必要ではないでしょうか?
実際には、画像が通常 128*128*128 double である 3D イメージングで何かを始めています。このようなものを書くことができれば、数学はずっと簡単になります:
q2: copy elision / RVO / move セマンティクスの組み合わせを使用すると、コンパイラは最小限のコピーでこれを実行できるはずですよね?
これを行う方法を理解しようとしたので、基本から始めました。コピーと割り当てを実装する従来の方法を実装するオブジェクトを想定します。
ここで右辺値を入力し、セマンティクスを移動します。私が知る限り、これは実用的な実装になるでしょう:
ただし、コンパイラ (VC++ 2010 SP1) はこれにあまり満足しておらず、コンパイラは通常正しいです。
q3:これを解決するにはどうすればよいですか? AnObject& operator = ( const AnObject& rh ) に戻ると確かに修正されますが、かなり重要な最適化の機会を失っていませんか?
それとは別に、move コンストラクターと代入のコードが重複していることは明らかです。したがって、今のところあいまいさを忘れて、コピーとスワップを使用してこれを解決しようとしますが、今度は右辺値を使用します。ここで説明したように、カスタム スワップは必要なく、代わりに std::swap にすべての作業を任せることができます。これは非常に有望に思えます。そこで、std::swap が move コンストラクターを使用して一時的に構成をコピーし、それを *this と交換することを期待して、次のように書きました。
しかし、それはうまくいかず、 std::swap が演算子 = ( AnObject&& rh ) を再度呼び出すため、無限再帰によるスタック オーバーフローが発生します。q4:誰かがその例で何を意味するかの例を提供できますか?
これは、2 番目の swap 関数を提供することで解決できます。
これでコードの量はほぼ 2 倍になりましたが、その移動部分はかなり安価な移動を許可することで報われます。しかし一方で、通常の代入はもはやコピー省略の恩恵を受けることができません。この時点で、私は本当に混乱しており、何が正しくて何が間違っているのかわからなくなっているので、ここで何らかの情報を得たいと思っています..
更新したがって、2つのキャンプがあるようです。
- 移動代入演算子をスキップして、C++03 で教えられたこと、つまり、引数を値で渡す単一の代入演算子を作成することを続行するようにというものです。
- もう1つは、移動代入演算子を実装し(結局のところ、現在はC ++ 11です)、コピー代入演算子に引数を参照渡しさせるように言っています。
(わかりました、そしてベクトルを使用するように私に言っている3番目のキャンプがありますが、それはこの架空のクラスの範囲外です。実際には私はベクトルを使用し、他のメンバーもいるでしょうが、ムーブコンストラクタ/割り当ては自動的に生成されません (まだ?) 質問はまだ保持されます)
残念ながら、このプロジェクトは開始されたばかりであり、データが実際にどのように流れるかはまだわかっていないため、実際のシナリオで両方の実装をテストすることはできません。そのため、単純に両方を実装し、割り当てなどのカウンターを追加して、約 2 回の反復を実行しました。このコードで、T は実装の 1 つです。
このコードは、私が求めているものをテストするのに十分ではないか、コンパイラがあまりにも賢すぎる: arraySize と numIter に何を使用しても、両方の陣営の結果はほとんど同じです: 同じ数の割り当て、タイミングにわずかな変動がありますが、再現可能な有意差はありません。
したがって、誰かがこれをテストするためのより良い方法を指摘できない限り (実際の使用シナリオがまだわかっていないことを考えると)、それは問題ではなく、したがって開発者の好みに任されていると結論付けなければなりません。その場合、私は#2を選びます。
c++ - 値によって返されるときに、値パラメーターは暗黙的に移動されますか?
次の関数について考えてみます。
return x
コピーコンストラクターまたは移動コンストラクターを呼び出しますか?(ここでNRVOを脇に置いておきましょう。)
調査するために、Foo
移動可能でコピー可能ではない単純なクラスを作成しました。
値パラメーターを値で返すときにmoveコンストラクターが呼び出された場合は、すべて問題ないはずです。return x
しかし、現在のg ++コンパイラは、次のエラーメッセージで文句を言います。
に置き換えるreturn x
とreturn std::move(x)
、すべて問題ありません。このことから、必要に応じて、値パラメーターからの移動を明示的に実行する必要があると結論付けます。g ++の動作は準拠していますか?
c++ - 移動可能なオブジェクトが最後に使用されたときに、コンパイラは自動的に移動セマンティクスを使用しますか?
私は最近右辺値参照を研究しており、オブジェクトの完全なコピーが作成されるあらゆる場所で値渡しを使用することは非常に有利であるという結論に達しました (完全な正当化については、右辺値参照演算子を追加するときに冗長コードを削減する方法などを参照してください)。オーバーロード?とWant speed? Pass by value! ) のような場合、コンパイラはコピーを自動的に最適化して削除できるため、f(std::move(a));
はf
として定義されvoid f(A a);
ます。
std::move
どこでも値渡しのマイナスの結果の 1 つは、次のような単純なケースであっても、すべてのコードが散らかってしまうことです。
明らかに、私が次のことだけを書いた場合:
a
ヒントがなくても、コンパイラが寿命の終わりに近づいていることを認識し、追加のコピーで私にペナルティを科さないことは難しくありません。実際、複雑な関数であっても、コンパイラはこれを認識できるはずです。
質問:
この最適化は C++0x 標準で許可されていますか?
コンパイラはそれを採用していますか?複雑なケースでも、つまり、関数が複数の行で構成されていますか?
この最適化の信頼性はどの程度ですか?つまり、コンパイラーが戻り値の最適化を適用すると予想するのと同じくらい、コンパイラーがそれを利用することを期待できますか?
c++ - C++ で qsort が機能しないのはどのような種類の型ですか?
std::sort
を使用して要素を交換します。これによりstd::swap
、コピー コンストラクターと代入演算子が使用され、値を交換するときに正しいセマンティクスが得られることが保証されます。
qsort
スワップする型に関連付けられたセマンティクスを無視して、要素の基になるビットを単純にスワップすることによって要素をスワップします。
qsort
ソートしている型のセマンティクスを知らなくても、自明でない型では非常にうまく機能します。私が間違っていなければ、POD タイプではないにもかかわらず、すべての標準コンテナーで動作します。
qsort
型で正しく動作するための前提条件T
は、T
/自明に可動/であることだと思います。頭のてっぺんから離れて、自明に移動できない唯一の型は、内部ポインターを持つ型です。例えば:
の配列をソートするとNotTriviallyMovable
、m_someElement
s は間違った要素を指すことになります。
私の質問は次のとおりです。他の種類のタイプでは機能しませんqsort
か?
c++ - C++11での関数呼び出しからstd::vectorを返す適切な方法(セマンティクスの移動)
std :: vector(または他のSTLコンテナ)に入力したい:
1.格好良いctor、高価なパフォーマンス
2.パフォーマンスが向上し、見栄えの悪いctor
get_vector
冗長なコピーやコンストラクター呼び出しを回避するために、C ++ 0x(セマンティクス機能の移動など)を使用して最初の例から関数を書き直すことは可能ですか?
c++ - 移動または名前付き戻り値最適化(NRVO)?
次のコードがあるとしましょう。
ここでは、コンパイラには2つのアプローチがあるようです。
(a)NRVO:xを破棄してから、xの代わりにf()を作成します。
(b)移動:一時空間でf()を構築し、f()をxに移動し、f()を破棄します。
標準によれば、コンパイラはどちらのアプローチも自由に使用できますか?