問題タブ [copy-and-swap]
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++ - コピー省略とは何ですか? また、コピー アンド スワップ イディオムをどのように最適化しますか?
Copy and Swapを読んでいました。
Copy Elision のいくつかのリンクを読んでみましたが、それが何を意味するのかを正しく理解できませんでした。誰かがこの最適化とは何か、特に次のテキストの意味を説明してもらえますか
これは単なる利便性の問題ではなく、実際には最適化です。パラメーターが左辺値 (別の非 const オブジェクト) にバインドされている場合、パラメーターの作成中にオブジェクトのコピーが自動的に作成されます。ただし、s が右辺値 (一時オブジェクト、リテラル) にバインドされている場合、通常、コピーは省略され、コピー コンストラクターとデストラクターへの呼び出しが節約されます。パラメーターが const 参照として受け入れられる代入演算子の以前のバージョンでは、参照が右辺値にバインドされている場合、コピー省略は発生しません。これにより、追加のオブジェクトが作成および破棄されます。
c++ - コピーアンドスワップの慣用句とは何ですか?
このイディオムは何ですか? また、いつ使用する必要がありますか? どの問題を解決しますか? C++11を使うとイディオムが変わる?
あちこちで言及されていますが、「それは何ですか」という単一の質問と回答がなかったので、ここにあります。以前に言及された場所の部分的なリストを次に示します。
c++ - パブリック フレンド スワップ メンバー関数
copy-and-swap-idiomに対する美しい答えには、少し助けが必要なコードがあります。
そして彼はメモを追加します
std::swap を型に特化し、フリー関数スワップと一緒にクラス内スワップを提供する必要があるという主張は他にもあります。 、そして私たちの機能はADLを通して見つけられます。1つの機能で十分です。
friend
私は「不親切」な言葉を少し使っているので、認めなければなりません。だから、私の主な質問は次のとおりです。
- 無料の関数のように見えますが、クラス本体の中にありますか?
- なぜこれは
swap
静的ではないのですか? 明らかに、メンバー変数は使用しません。 - 「スワップを適切に使用すると、ADL を介してスワップが検出されます」 ? ADL は名前空間を検索しますよね? しかし、それはクラスの中にも見えますか? それとも入ってくるのはここ
friend
ですか?
補足質問:
- C++11 では、
swap
s を でマークする必要がありnoexcept
ますか? - C++11 とそのrange-for
friend iter begin()
では、friend iter end()
同じようにクラス内に配置する必要がありますか? ここでは必要ないと思いますfriend
よね?
c++ - 安全な割り当てとコピーアンドスワップのイディオム
私は c++ を学んでおり、最近 (ここではスタック オーバーフローで) コピー アンド スワップ イディオムについて学びましたが、それについていくつか質問があります。たとえば、コピー アンド スワップ イディオムを使用する次のクラスがあるとします。
私の質問は、データとして Foo オブジェクトを持つが、カスタムのコピーや割り当てが必要なポインターやその他のリソースを持たない別のクラスがあるとします。
今、私は一連の質問があります:
クラスに対して上記で実装されたメソッドとコンストラクターは
Bar
安全ですか? コピーアンドスワップを使用してFoo
、割り当てまたはコピー時に害がないようにしBar
ますか?コピーコンストラクターとスワップで引数を参照渡しすることは必須ですか?
の引数が
operator=
値渡しされると、この引数に対してコピー コンストラクターが呼び出されて、オブジェクトの一時的なコピーが生成され、次に と交換されるのはこのコピーであると言うのは正しい*this
でしょうか? 参照で渡した場合operator=
、大きな問題が発生しますよね?このイディオムがコピーと代入で完全な安全性を提供できない状況はあり
Foo
ますか?
c++ - 一部の人々が移動割り当てにスワップを使用するのはなぜですか?
たとえば、stdlibc++ には次のものがあります。
2 つの __u メンバーを *this に直接割り当てないのはなぜですか? スワップは __u に *this メンバーが割り当てられていることを意味しませんか?後で 0 と false を割り当てただけです...その場合、スワップは不要な作業を行っています。私は何が欠けていますか?(unique_lock::swap は、各メンバーで std::swap を実行するだけです)
c++ - 移動可能でコピー不可能なクラスでmove-and-swapイディオムを使用することは理にかなっていますか
私のようなクラスがある場合
コピーコンストラクターがない場合は、operator = by valueとswapを実装するのは理にかなっていますか?クラスのオブジェクトのコピーを防ぐ必要Foo
がありますが、移動は許可します。
このクラスはコピーできないので、構成をコピーしたり、コピーして割り当てたりすることはできません。
編集
私はこれで私のコードをテストしました、そしてそれは私が望む振る舞いをしているようです。
c++ - コピー アンド スワップ イディオムの再利用
コピーアンドスワップのイディオムを再利用可能なミックスインに入れようとしています:
CRTP経由で混合するつもりです:
ただし、簡単なテストでは、機能していないことが示されています。
これは「デフォルト」を 2 回出力するだけで、「コピー」も「スワップ」も出力されません。ここで何が欠けていますか?
c++ - コピーアンドスワップを使用したテンプレートクラスを使用した未解決の外部
ここで提案されているように、コピーアンドスワップイディオムを実装しようとしたテンプレートクラスを使用すると、リンカーエラーが発生します。
テンプレートクラスを「TemplateClass」と呼びましょう。部分的に次のように定義されています。
.hファイルに含まれている別のTemplateClass.cppに実装を配置しました。(編集:すべてが.hファイルにある場合、同じ問題が発生します)
代入演算子は次のように定義されます。
スワップ方法は次のように定義されます。
(心配しないでください、私は実際に私のメンバーに「member1」などの名前を付けません)
同じように定義された同様のクラスがありますが、テンプレートクラスではありません。ここではすべてが正常に機能します。TestClass
ただし、メンバーを持つクラスがありTemplateClass< HandledClass > member
、そのメソッドの1つで次のような呼び出しを行う場合
未解決の外部エラーが発生します:
LNK2019:関数 "public:class TemplateClass X&__ thiscall TemplateClass X :: operator =(class TemplateClass)"(...)の未解決の外部シンボル "void __cdecl swap(class TemplateClass&、class TemplateClass&)"(...) TestClass.obj内
または言い換えると、TestClass
呼び出しTemplateClass<HandledClass>::operator=
で何かが見つからないvoid swap( TemplateClass<HandledClass>, TemplateClass<HandledClass> )
。
だから私の質問は:なぜオペレーターはスワップメソッドを見つけられないのですか?
テンプレート引数用にコンパイルされていないようです。コンパイラにフレンドボイドもコンパイルさせることはどういうわけか可能ですか?
私はおそらくfriend void
アプローチを捨てて、クラス内のスワップメソッドとクラス外のスワップメソッドとstd名前空間の1つを定義することができますが、それがそのように機能するかどうかはわかりません。とにかく可能です。
解決:
これは仕事をしました:
<T>オカレンスも削除する必要があることに注意してください。
visual-c++ - MFC CStringを交換するにはどうすればよいですか?
OK、それで私はすべてコピーアンドスワップのイディオムで売られており、私はそれを実装する方法をほとんど知っていると思います。
ただし、またはコードベースはMFCのCStringクラスを文字列として使用するため、これは変更されません。
swap
しなければならない(すべきか???)ので、私はできません
これにより、スローされる可能性のある一時的なCStringオブジェクトが作成されます。(それに加えて、その非効率的です。)
だから私はどこに残っているのですか?トライキャッチを追加する必要がありますか?これ(非常にまれですが)のメモリ不足状態で例外を発生させ、スワップを失敗させることを実際に許可する必要がありますか?
CStringsの実装を見ると、スワッピングを可能にするメンバーまたは関数がないようです...