C++相談室 part136
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の1行目に以下を追加して下さい。 !extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part135 https://mevius.5ch.net/test/read.cgi/tech/1522495206/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.102【環境依存OK】 http://mevius.5ch.net/test/read.cgi/tech/1509780815/ ■長いソースを貼るときはここへ。■ http://codepad.org/ https://ideone.com/ [C++ FAQ] https://isocpp.org/wiki/faq/ http://www.bohyoh.com/CandCPP/FAQ/ (日本語) ----- テンプレ ここまで ----- VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured >>64 スマポ=シャローコピーって意味わからん unique_ptrを使わずにナマポでpimplとか今となっては考えられんのだが >>50 DoxygenがC++17の新構文に対応してないだけでしょ まだ仕様が確定してないから対応してないよってどっかに書いてあったような気がする >>64 所有権を移転*しない*ということを表現できるのもスマートポインタの使い方のひとつだよ。 >>68 はぁ??? pimplてあんなもん生存期間がシンプルすぎて スマートポインタなんか要らない例だろキチガイかお前 ナマポでもpimplはできるが 毎度毎度わかりきったコードを書く 無駄な手間がちょっとイヤ pimplに限らないが、メンバーにunique_ptrを使ったときの空のデストラクタが悲しい。 JSはES6でスゲー良くなった希ガス もはやC++やPerlみたいな工業用言語として十分逝ける URLから連想出来る署名は IQ110のJS先輩と学ぶ関数型プログラミング14日間 >>71 生存期間がシンプルすぎるからunique_ptrが入らないっていうのは賛同できないわー。 将来デストラクタが複雑になって誰かがdeleteする経路をすっ飛ばしてreturnしてしまうかもしれんし、使えるところは使っておけばいいじゃない。 何を気にしてunique_ptrさけてるの? >>70 それで何が嬉しいんだ? ついでに質問しておこう。 君はCのような自前でリソース管理をしなければならない言語でリソース管理をしたことがあるか? あと、これはC++er全般に対してだが、 shared_ptrが絶対に必要なケースってのは何だ? unique_ptrで後述A,B以外の使い方Dがあるか?(なおCは予約語) Cでのリソース管理戦略は非常に単純で、おそらく以下の2つしかない。 A. 作成者が責任を持って破棄する。 B. 投げ捨て。基本的に所有権を渡し、末端(付近)で破棄する。 Aが基本パターンになる。 Bは例えば描画用の一時データ等の場合で、 この場合、使用するのは「描画ルーチン『だけ』」であり、それ以降は不要だと自明だから、 ・「描画ルーチン」までの途中経路での使用は原則禁止 (厳密には、「描画ルーチン」呼び出し以降の使用は禁止で、 呼び出し以前は改変等を加えてもいい=この例なら、描画スケールの改変等) ・「描画ルーチン」内で必ず破棄 となる。 ただしあまり気にしないのならBも使わず、Aだけで組んでも問題ない。(というか多分そっちが主流か?) 描画の例であれば、描画終了後は普通はかなり速やかに親関数まで帰ってくるので、 親関数側でfreeするA方式でも大差ないからだ。 対して、OOP的に実装した場合、例えばゲームの敵キャラの生成/消滅を管理するとして、 この場合は「描画ルーチン」のように 「静的に明示的に生成/消滅の両方を内包する親関数」が規定出来ないので、 A方式は事実上使えず、Bで対応するしかない。だから上記を書き直せば、以下となる。 A. 「作成/使用の両方を静的に管理下に持つ親関数」を規定出来る場合、(=構造化プログラミング) その親関数内で確保し、親関数のスコープ終了と共に破棄する。 B. 上記親関数を規定出来ず、「作成」「使用」場所が明示的な場合、(=OOP) 「作成」後は基本的に所有権を譲渡し、「使用」後に破棄する。 既に言ったように、Cの戦略は多分この2つだ。というか、正確に言うと、これ以外での管理は無理だ。 そしてこれはC++では以下のようになる。 A. 自動変数上のunique_ptrに確保、関数呼び出しでは所有権の移転はしない =生成場所のスコープ終了と共に破棄、それ以外の破棄はない B. unique_ptrに確保し、自関数を抜ける前に『必ず』誰かに所有権を移転する 自関数が対象関数(上記例なら描画関数)であれば、移転相手がいないので破棄する だからはっきり言えば、Cのナマポは事実上C++のunique_ptrの使い方しか出来ないし、してない。 C++erがスマポ(キリッなのは、上記C流のリソース管理を知らない=無知だからでしかない。 繰り返すが、Cは最初からunique_ptrしかないのと等しい。 ここがC->C++の連中と、C++しか知らない馬鹿との違いだ。 これに対して、shared_ptrは上記制限を解除するものだ。 だからshared_ptrを使えば新しいプログラミングパラダイムを発見出来る可能性はある。 これは何だ? 俺にはこれがイマイチ思いつかない。 いわゆる構造化プログラミングで、関数を入れ子で呼んでいく場合、必ずAは適用可能だ。 これがCが今までのさばっている理由でもある。 OOP的に組む場合はBが基本戦略となり、必ず誰かが明示的に「生成」し、 同様に、必ず誰かが明示的に「破棄」するので、これまた問題ない。 だから今のところCで間に合っているのも事実だ。 リソース管理が「面倒だ」というのは分かるとしても、 「難しい」というのは根本的に組み方を間違っているからだ。 GC言語しか知らない馬鹿共が知らないのは当たり前だとしても。 shared_ptr等が必要なプログラミングパラダイムが発見され、 それに対応する方法がなければ、お前らの望み通り、Cも死ぬしかない。何かないのか? 或いは上記A,B以外のunique_ptrの使い方Dがあるか?(なおCは予約語) 例外安全性の確保でウッカリさんするくらいなら使った方が良い。 >>79 誰かがdeleteする経路をすっ飛ばしてreturnってどゆこと? スタック巻戻しを破綻させるものってstd::exitくらいじゃね >>80 >それで何が嬉しいんだ? お前さんが大好きなC言語の関数にポインタを渡す場合 >>68 ,79 そもそもpimpl自体が要らんだろ。 あれはC++のコンパイラが単純に仕様変更 ・ヘッダにはprivate関数は書く必要がありません すればいいだけの話で、そもそも「名前空間は開いていますが、クラスは閉じています(キリッ」を、 「ヘッダのクラスは開いていますが、実装のクラスは閉じています(キリッ」にすればいいだけ。 編集上の都合でソースが汚れるとか、全く馬鹿な話だろ。 気づけよ。 pimplに近いテクニックとしてC言語の頃から絶縁テクニックというものがあるが それをやると大概静的解析ツールが横暴な量の警告メッセージを吐いてきやがるので却下 pimplも多分同じ結果に… Javascriptを使って感じるC++の有利な点は仕様の明確さだろう。 Javaは重いと言われユーザーに嫌われる言語のひとつだが、開発者はベンチマークを提示しC++の20倍速いと言う。 しかしユーザーは実際に重くて困っているだろう。 ブラウザも同じ問題を抱えていて、当然Javascriptも重いとユーザーは感じている。 Microsoft社はソフトウェアの使用状況を監視させてほしいとユーザーにお願いする。 IMEの誤変換データや、プログラムのクラッシュ時の情報などだ。 これらは、開発者とユーザーの間の意識の乖離を埋める可能性がある。 ユーザーの重いと開発者の軽いのような。 オープンソースに対するアドバンテージがここにあるのかもしれない。 >>90 慣れたらJQueryなど使わずとも複数プラットフォーム対応逝ける! >>91 Microsoftはつい先日GitHubを買収したから ソースコード自体を監視に乗り出すようや Visual StudioはCMakeに対応したし、Microsoft社はオープンソースとの付き合い方をやっと学んだようだ。 >>84 たいしたこといってないです。 ~dtor() { . if (...) { . return; . } . delete ptr; } >>86 pmplがバッドノウハウに属するものであることは同意だけどprivateメンバ変数はどうするつもり? pimplを多用するライブラリの一つにQtがある。 C++はテンプレートによって拡張性を担保できる言語だ。 一方、拡張性はライブラリのユーザーにとってわかりやすさを損なう。 IDEとの結合において、pimplによる公開は一つのテクニックかもしれない。 ところでpimplってぽいんぷるって読むんだよな? >>82 cで参照カウント使ってる例なんていくらでもあると思うけど。例えばキャッシュとか。 参照カウントを自前で書けばいいからshared_ptrはいらないって言ってるわけではないよね? キャッシュは不意のアクセスに備える目的のやつだから 今誰もアクセスすなくなったからといって即開放(例: キャッシュラインをinvalidate)したら意味半減くね…? というわけで、参照カウントの使用例としては不適切くね…?? それはそうとして、 資源の開放タイミングをスマポに頼るのは負けというC言語スキー氏には概ね同意だが プログラマーが後始末タイミングをどうしても決められないシチュは存在するからスマポは要る GCのように、開放タイミングを決めるのが未来のプログラマーなケースがそれ >>95 いい突っ込みだ。 今の実装だと、最低限プライベートの全サイズは要るのか。 Javaとかどうしてんだろうな? 現実的な解としては、 privateフィールドについてはコンパイラが自動的にpimpl的に間接参照に切り替えだな。 どうせpimplにする気だったのなら速度的にも大差ない。 いずれにしても、今の時代、コンパイラに合わせてコードを書くのは間違いで、 人間に合わせてコンパイラが努力するのが正しい。 >>80 ワイはオッサンやで。 C++98 が出来る前から C も C++ も使ってるというか、 マイコンで BASIC とアセンブラが主流だった時代の人だで。 そのときは何にも疑問に思わなかったけど、 今どきのモダンな仕組みを知ってしまったら、 昔の牧歌的なリソース管理なんて本当にしたくねぇという気持ちなんだよ。 (かといって使い慣れたパラダイムから離れるのも面倒くさい。 オッサンなので。) >>81-82 そこで unique_ptr を使うことに疑問を持つことが意味わからんのだが。 まさにそういう風に使うためのもんだし、 その例で unique_ptr への懐疑を説明されてももう俺には何にも言えねぇ。 >>101 参照されている間も消していいキャッシュなら参照カウント不要だけれども、そっちのほうが稀じゃね? >>100 > 参照カウントを自前で書けばいいからshared_ptrはいらないって言ってるわけではないよね? そういうわけではない。 ただ、参照カウントを自前で書いても大して苦労しないのも事実だが。 > 例えばキャッシュとか。 これはいい例に見えるが、実はちょっと違う。 まず、これは「生存期間にデータ依存性がある為、上位関数からではde.lete出来ない」例ではある。 ただ、実際にキャッシュを実装すると、 1. non_sharedのキャッシュの場合、要するにLRU判定で捨てるときにそのままdeleteすれば良いだけ。 2. shared_cacheの場合、例えばCPUのキャッシュのエミュレーションを行う場合、 書き込みで他CPUのキャッシュを無効化するとか、その手の上位側の制御が必ず必要で、 shared_ptrだけでサクッと実装、ってことにはならない。 だから、Cで実装してもC++のスマポで実装しても、実は手間があまり変わらない。 それではおいしくないんだよ。 勿論、「書き込み無し」とかだと、破棄の制御をしなくていい分C++の方が楽に実装出来るが。 つまるところ、shared_ptrは、 手抜きデタラメ実装する場合は凄く便利だが、ガチで実装する場合にはあまり恩恵がないんだ。 とりあえず、キャッシュの場合はそう。 ってのが>>101 の意見でもあると思うが。 >>104 キャッシュは、存在すればアクセスのレイテンシーが短縮されるというラッキーをクライアントに提供するだけのしくみ よって、キャッシュ上のデータというのは基本いつ消してもシステムにとって致命傷にはならず、 かつ可能な限りキャッシュ上に残存するように普通は設計する 参照カウンタが0より大きいからキャッシュ上のデータを消してはいけないという法は無い 一方、仮に>>104 で言いたいのがアクセスしている最中に消したらアカン、という話なのであれば、 それは排他制御の話題であってそれも参照カウントとは関係無く言える話やし… >>101 スマポは未来のプログラマーが解放することを「文法的に」示す意味しかない。 例えば、mallocも同様だが、 当然ナマポが返ってきて、それを解放するのは未来のプログラマー責任になっている。 要するに「そういう使い方」を規定すれば済むだけなんだよ。 unique_ptrが必要ないというのは、C++を使ったことがないってことだから、C++を使ってる人に対して、unique_ptrを使うべきでないと意見しても意味がない。 必要だから使ってるんだし。 >>103 俺はunique_ptrは「C的リソース管理を文法的に示す」意味しかないと見てる。 反対する意味もないが、積極的に使う意味もない。 元々そうとしか組めないし、既にコードはそうなってるから。 だからunique_ptrに書き換えろってのは、相当にウザイ。 他言語だとforeachをforに書き換えろとか、あれと同じじゃないかな。 たぶんLinusもこれなんだよ。 C++の奴は新しい文法でやることに意義を感じているようだが、 それによってソースコードの構造が改善されるかというと、全くそうじゃない。 むしろ、おかしくなることの方が多いわけでね。pimplとかもそうでしょ。 > 昔の牧歌的なリソース管理なんて本当にしたくねぇという気持ちなんだよ。 これがよく分からん。 というか俺はリソース管理したくないから当然のごとくGC言語を使っているわけで、 そこまでしてC++に拘る理由が分からん。 スマポ使えというなら、うるせえGC言語使え、と返したい。 Cより開発効率が高く、Javaよりユーザーにベネフィットを提供できる。 そういった観点から、広く使われるソフトウェアの開発にC++を採用するのは理にかなっている。 JavaにしろC#にしろ、GUIライブラリがころころ変わるのは、エンドユーザーが受け入れないからだろう。 そう、馬鹿なユーザーはJavaやC#の利点を気にかけないのだ、自分のことしか考えない利己主義め! なぜ重いソフトウェアを使うべきなのか、ユーザーをキチンと教育する必要がある。 あるいはC++を選ぶ。 >>107 >スマポは未来のプログラマーが解放することを「文法的に」示す意味しかない。 スマポでできて、free()ではできないことがあるからその言い分は違うくね? いやまあ>>101 でGCとしか言わなかったのは言葉足らずだったので今条件を追加するが、 こちらが実装上の都合で用意するオブジェクトの数と、未来のプログラマーに対して見せかけるオブジェクトの数が相違するケースでは どうしてもスマポ的な手段に訴える(オブジェクト自身に開放タイミングを決めさせる)必要があるんじゃー! 例えば画像データみたいに巨大故に必要無い限りコピーしたくないんだけどそんな事情をライブラリ利用者から隠蔽したいケース あるいは、やっぱGC自体が行う本来のガベージコレクション業務タイミングを決める方法とか、 (GCがシステムに1個しか無いのに対して、ユーザーは潜在的に多数でありGCの存在を関知せずに使ってくれる 一方、「必ずfree()せよ」という仕様には、malloc()したヒープ1個の開放以上の意味を持たせられない std::unique_ptrを使用したくない局面では、テンプレート仮引数Allocatorを用意するべきである。 つまり、ほとんどの場合、std::unique_ptrが有用である。 >>111 > 例えば画像データみたいに巨大故に必要無い限りコピーしたくないんだけどそんな事情をライブラリ利用者から隠蔽したいケース なるほど理解した。 ここでshared_ptrを渡して多数に見せかけ、実は中身は一つ、という話か。 となると、当然インミュータブルでないと話にならないわけだが、 逆に言えば、今時のインミュータブルな世界にはshared_ptrが大活躍する余地があるのか? すぐにはピンと来ないが。 >>113 △: 当然インミュータブルでないと話にならないわけだが、 ○: 当然インミュータブルなインターフェースでないと話にならないわけだが、 実装は別にミュータブルでもクラスで覆うならやりようはいくらでもあるんじゃ… 画像の書き換えを専用メソッドでやるか、あるいは速度優先でcheckout/checkin式にcheckout中だけ直接アクセスを許すとか、 (もちろんcheckout時にコピーを行う で、内部ではshared_ptr(的な、「オブジェクト自身に開放タイミングを決めさせる」)ロジックが大活躍!!111!!!!1! >>111 いや待てよ、コピーオンライトなスマポがあればミュータブルな世界にも適用可能だが、 今の所、これはないよな? いずれにしても適用事例はすぐには思いつかないが。 訂正; ×: あるいは速度優先でcheckout/checkin式にcheckout中だけ直接アクセスを許すとか、 ○: あるいは書き換え速度優先でcheckout/checkin式にcheckout中だけ画像への直接アクセスによる書き換えを許すとか、 C++を解った気になった奴らがアンチパターンを量産する >>114 ,116 まあ分かった。 多分shared_ptrは『ほぼ』インミュータブルな世界とは相性がいい。 (ミュータブルにする必要がほぼなく、その場合は明示的に別メソッドを呼んでもいい場合) つっても適用事例はWebサーバーくらいしか思いつかない。 ある画像が人気でユーザーが一斉にダウンロードしたとして、 鯖内部に30秒間だけキャッシュする場合とか。 ナマポで渡した場合、各ユーザーのダウンロード完了でカウントを減らし、0になるまで破棄出来ない。 shared_ptrで渡した場合、30秒の期限が過ぎればキャッシュから破棄しても問題ない。 この辺は確かに楽に組めるようになる。 >>118 キャッシュにstd::shared_ptrを使用するのは愚策すぎるのではないか。 実のところstd::shared_ptrはほとんど出番がない。 設計を練れば練るほど出番は失われていく。 いやすまんインミュータブルなインターフェースといいつつ>>114 では画像を書き換えるインターフェースの話をしてしまったスマンorz 「画像の書き換えを専用メソッドでやる」は、「加工後の画像を専用メソッドで生成する」、と読み替えてホスイ で、ライブラリが画像Aを生成し、その画像がライブラリのユーザーによって不特定多数のクライアントとのセッションスレッドに渡されるシチュを考える セッションスレッドの具体的な数は事前にはわからない。(接続してくるクライアント次第 また、何らかのタイミングでクライアントに提示すべき画像Aは、別の画像A'に差し変わる。 ライブラリのユーザーとしてはスレッド間の排他制御に関して面倒な問題を抱え込むのは嫌なので、 メインスレッド(セッションスレッドを起こす)から、画像Aのコピーを、所有権を譲渡する形でセッションスレッドに渡す、という使い方をする。・・・(1) ライブラリ内部では、(1)の使い方をされるときにいちいち画像Aをコピーしたりしない。 画像Aの開放は、画像AがA'に差し変わるタイミングで行いたい。 ただし、画像Aを使っているセッションスレッドが居る間は開放するわけにはいかない。 しかし、当該スレッドがセッションを終えるのを待っていたら、新規につないで来るクライアントへの画像A'の提示が遅れる →画像Aの開放タイミングはスマポで解決! >>118 ちょっまだキャッシュ言いますかキャッシュと参照カウントは原理上無関係なので(>>106 )忘れてよろしいかと、 (参照カウンタが0より大きいからキャッシュ上のデータを消してはいけないという法は無いし、 参照カウンタが0になったからといってキャッシュ上のデータを消さなければいけないという法も無い Webサーバというのは適用事例として好適だがダウンロード中かダウンロード完了か、という区分でしか考えないのはイクナイ ダウンロード中にも新規のクライアントがつないでくるかもしれない そのときダウンロード完了時に画像を破棄すればいいやという単色の思考だと、新規のクライアントが繋いで来つづける限り 画像を永久に開放できないことになり、そればかりか>>120 のように、画像をAからA'に差し替えることもできない これは画像Aの開放を、画像Aのオブジェクト自身に面倒をみさせるしかない(自身を参照するセッションスレッドが0になったとき開放させる サーバはそれとは並行して画像A'を新規のセッションスレッドに展開できる。 こんな芸当ができるのはスマポだけ! >>121 言いたいことは分かるが、 > 画像をAからA'に差し替えることもできない これはない。 この場合はどのみちキャッシュを別実装するしかなく、 ・キャッシュ内に画像Aへの参照が残っているか ・画像Aを掴んでいるセッションが存在しているか が別問題になり、 画像の差し替えはキャッシュ内の画像Aを無効化することにより行われる。 だから、普通に差し替えは出来る。このとき、 それ以前のセッションは画像Aのまま、それ以降の新規セッションは画像A'になる。 ただまあ、これは本筋ではないし、内容見る限りそちらも分かっているようだからもういい。 多分、shared_ptrの使いどころは、 1. インミュータブルなインタフェースで、 2. 不特定多数がランダムに掴みに来て、 3. 解放タイミングがユーザー依存で読めない場合 なのだろう。アプリはWeb鯖はそうだが、それ以外に何があるかだな。 1,3はさておき、2がね。 少数しか来ないのならunique_ptrでいいし、 演算等CPUジョブなら結局は順に処理するだけなのでこちらもunique_ptrでいい。 I/O等の他要因で引っかかってスレッドが参照を掴んだまま待機させられることが必要になる。 ファイルサーバーも近いが、こちらの場合はロック機構が必要な為、 「どのファイルが今何人にどういった権限で捕まれているか」の管理が必要であり、該当しない。 (shared_ptrを使っても大して楽にはならない) 一応簡単に俺の主張を纏めておくと、 ・unique_ptrは従来C方式を文法的に強制させるだけで、コードの改善には繋がらない。 ・shared_ptrの使いどころはWebサーバーしか思いつかない。 GC言語は基本的にshared_ptrなわけだが、あれって基本的に手抜き専用で、 GCがないと本質的に辛いって構造はあんまりない。 Rustも今更GC無しですかー、とも思うが、実際、無しなら無しでもいいか、程度ではある。 >>123 その GC が大問題 現状 GC の最終手段は mark and sweep なので、これが嫌だ、という価値観はありだとおもう >>109 > 俺はunique_ptrは「C的リソース管理を文法的に示す」意味しかないと見てる。 その意味がすごく重要やん? 漠然としてたものに区別を与えてくれる最高の機能じゃんね。 >>95 期待して損した そんな自殺コードを書かれるのを防ぐのは スマポじゃなく人事部の仕事だ 「バカよけ」機能に価値はない、無駄だから使わないしコードが長くなるから使わせない っていう老害いるよね そういう奴に限ってバグや脆弱性作り込むんだけど決して反省しない std::unique_ptrを導入すると人事部から一人削減できるってことじゃないか。 >>128 まあ俺も老害とか言われることのある世代だが 価値がないのは「バカよけ」ではなく「バカ用」な バカなふりをする達人をニヤリとさせるのではなく、 どうしようもない真性バカを延命する機能は有害なだけ >>127 期待するも何も、スタック巻き戻したらどうしてヒープ開放されると思ったのさ? >>132 デストラクタが実行されるからさ スタック巻戻しとは何たるかわかってる? 混乱を避ける為に先に質問しておきたいんだが、 上記A(82)の場合、つまり、 親関数から子関数にポインタを渡したいが、所有権を移動しない場合には、どう書くんだ? ざっと探しても出てこないんだが。 引数に値渡ししたらムーブ、これは分かる。 ムーブしたくないが子関数に渡したい場合は? すまん、>>134 はunique_ptrの場合。もう一度書き直すと、 親関数から子関数にunique_ptrを渡したいが、所有権を移動しない場合には、どう書くんだ? >>124 それはありだ。 ただし、俺は「循環参照の場合に回収出来ないGC」であってもいいと思っている。 循環参照が必要なケースはほぼ無いので、明示的に切ってから解放でいい。 これはweak_ptrと同じで、C++erなら同意してもらえると思う。 ついでにいうと、「コンパクションが出来ないGC」でもいい。 これなら**ptrにする必要なく、*ptrで行けるから速度低下も起きない。 つまり、仕様はC++どおりでいいが、 プログラマにやらせるな、自動でやれ、ということ。俺的には。 >>135 なんだよ!所有権の複製もできないのかよ!? やっぱりstd::unique_ptrダメじゃん!!!! >>137 まあそのネタはさておき、マジで探しているのだが出てこない。 知ってたら教えてくれよ。 これ、もしかしてget()してナマポ渡すしかないとかいうオチ? ならunique_ptrなんてマジでゴミだぞ。 さすがにそれはないと信じて探しているのだが、マジで出てこない。 >>138 参照で渡せばいいんじゃないのか? そんなことして何の意味があるのか知らんが。 std::unique_ptrに対するweak_ptrは無いぞ。 だからゴミだという場合は、>>137 。 >>139 俺も最初はそうかと思っていたんだが、実はそれも出てこないんだよね。 まあでもそれで、コンパイラが最適化をするのを期待する、というC++的オチか? これはあり得るとは思うが。 >>141 当たり前すぎて出てこないだけでは? auto result = my_func(*my_unique_); とすればいいだけなんじゃないの? std::unique_ptrを利用する主な動機は総称型を保持するためなんだよな。 >>140 そういう意味ではないが、 > std::unique_ptrに対するweak_ptrは無いぞ。 この表現は分かりやすい。 >>142 それは実体を値渡ししてしまうだろ。 >>144 lvalue_referenceだから仮引数側でどうにでもできるだろ。 参照だけするスマポ(と言いつつ何もしないアホの子スマポ)は次の規格で検討されてたでしょ observer_ptrだかexempt_ptrだか名前コロコロ変わってるけど >>146 だから違うっての >>147 多分俺が欲しいのはそれだ。 https://en.cppreference.com/w/cpp/experimental/observer_ptr 要するに、「ナマポだがdelete出来ない物」が欲しい。 unique_ptrは値渡しすると所有権が移動してしまう。 関数にはポインタの場合値渡しが最速だし、自明だから、グダグダ書いて最適化を待つ、とかやりたくない。 生成は常にunique_ptrからの値コピー(所有権は移動しない)でいい。 寿命管理は他に任せるが、ナマポと完全に同パフォーマンスの物、これが欲しい。 まあ、検討中ならよかった。 deleteされたくないポインタと言えばこうだろ。 https://ideone.com/PvzDVY >>125 > 漠然としてたものに区別を与えてくれる最高の機能じゃんね。 俺の理解が正しければ、これはダウト。表現力が足りない。 今のunique_ptrはB用のインタフェースしか持っておらず、Aを最速では記述出来ない。 足りてないのは、既に言ったとおり、「ナマポと同速だがdelete出来ないスマポ」。 だからやっぱイマイチなんだな。 とはいえ確実に拡充されてるから、最終的にどうなるかは見物だが。 高位機能も最終的には追いつくだろうし。 ただ、C++はプログラマの努力で何とかしようとしているが、 そもそもAにしてもBにしてもコールグラフの解析でfree忘れとか抜けるはずなんだよね。 Cの連中はこの辺には興味ないみたいだけど、 人手でやってる分、スマポみたいにコーナーぎりぎりを攻められないから、 ある程度わかりやすいところでfreeされてる。 当然、ツールにもかかり易いはずで。 それ参照でいいだろ。 言ってる意味が全く分からない。 私もはやく皆さんとお話したいのですが、内容が全くわかりません。 C++でRPG作れる程度の知識なのですが、何から学べば良いでしょうか。 おすすめの本、サイトがあれば教えてくださいが >>152 それならば effective C++ / effective modern C++ がいいかと思います そりゃC++使ってる人が読んだって全く分からないだろうな。 >>122 >1. インミュータブルなインタフェースで、 >2. 不特定多数がランダムに掴みに来て、 >3. 解放タイミングがユーザー依存で読めない場合 ちゃうねんそれでは表層的な観察にすぎなず、 shared_ptr(的な、「オブジェクト自身に開放タイミングを決めさせる」(>>114 ))処理の必要性の1断面でしかないねん >>121-122 が言っているのは、 >こちらが実装上の都合で用意するオブジェクトの数と、未来のプログラマーに対して見せかけるオブジェクトの数が相違するケース(>>111 ) において、未来のプログラマー(ユーザー)がオブジェクトをコピーしたつもりだが実装の内部ではコピーしていなくって、 ユーザー視点では自身のプログラムが保持する独立した1オブジェクトを開放したつもりが、実は内部の実装の都合において、 ユーザーまたはユーザー2のプログラムが保持する別のオブジェクトの開放と関係を持ってしまうケース(∵実体が同一)において shared_ptr的な、「オブジェクト自身に開放タイミングを決めさせる」(>>114 ))処理が必要ということなんじゃー .>>122 >画像の差し替えはキャッシュ内の画像Aを無効化することにより行われる。 これは>>121 のケースでは問題の解決にならない。 なぜなら、仮にキャッシュ上に画像Aを用意してあり、最後まで画像Aを掴むことになったセッションXに対して セッション開始時にメインスレッドが渡したのがキャッシュ上の画像Aだったとしても、 渡した瞬間にセッションとキャッシュの関係は切れるからじゃわ!(半切れ >>121 は、セッションXは自身のローカル記憶(のつもり)であるところのオンメモリの画像Aを使い、 セッション終了時に開放する、ということしか言っておらず、 セッション中に2回3回とキャッシュ上の画像Aを取りにいくとは書いては いない キャッシュとセッションXの関係がセッション開始時の一瞬でしかない想定な以上、 画像Aの実体の開放に関してキャッシュの無効化機構をどう別実装しても無駄。問題に影響無し。 ちな「キャッシュの無効化機構」とは、新規セッションに見せかける画像をAで無くすしくみという意味であって(それ以外の読み方をせよというのは_)、 画像Aの実体の開放とは関係ありませんからぬ、 というわけで繰り返しになるが画像Aの実体の開放に関してキャッシュの無効化機構をどう別実装しても無駄で、 画像Aの実体の開放はshared_ptr的な、「オブジェクト自身に開放タイミングを決めさせる」(>>114 ))処理の専任事項となる (>>121 の想定のように画像Aが複数に見えることもあるが実体は唯一、というときはそうする以外画像のAからA'への差し替えは_ >>155-157 まず、俺の意図が正確に君に伝わっていることは分かった。 が、Webサーバーなんてそんなもんだろ。(…α) 画像『ファイル』Aを鯖からダウンロードしている最中に、鯖上で画像『ファイル』がA'に変更されたとしても、 ユーザーは画像Aをダウンロードし続ける。 それどころか、鯖は更新された画像A'に即座に対応することすら期待されていない。 2-3分の遅延なら許容されている。 この仕様においては鯖上のオンメモリキャッシュとファイルの同期は厳密にとる必要はなく、 俺の示した実装の通りであり、それは君にも正しく伝わっている。 この場合はshared_ptrでの実装の方が楽だ。(ただし厳密には問題があるが) 一方、ファイルサーバーはそうではない。(…β) Webサーバほどの多人数が同じファイルを同時に掴みに来ることはほぼ無いが、 「どのファイルが今誰にどういった権限で捕まれているか」を完全把握しなければならず、 ファイルの更新、ファイルロックのリリースも即座に対応することが期待されている。 許容されるのは精々数秒でしかない。 この場合は上位の制御が必ず必要になり、shared_ptrが有ったところで大して恩恵はない。 違いは単純で、「厳密な同期が必要とされているか」だ。 だからもし、君がMMORPGのような多セッションでの 鯖上『オンメモリ』画像AからA'への切り替えを想定していたとしても、(…γ) それはshared_ptrでの実装では楽にはならない。 画像A->A'への切り替えを同期させるなら、「誰が画像Aを掴んだままか」を鯖側が把握せねばならず、 上位の制御が必ず必要になる。shared_ptrを配って終わり、にはならない。 これは結局、Web鯖上の『ファイル』に対するキャッシュ条件がユルユルだから発生した特殊事例であり、 俺が言ったとおり、 > 手抜きデタラメ実装する場合は凄く便利だが、ガチで実装する場合にはあまり恩恵がない (105) でしかない。 勿論それが許容されている世界であり、スループットを取っているだけだからそれでいいんだが。 が、とにかく君は、 > オブジェクト自身に開放タイミングを決めさせる 事が必要だと思っているらしい。これの他具体例はあるか? 君が挙げてきた別例はGCだが、現実問題として、ほぼunique_ptrで事足りるのも事実だろ。 shared_ptrは機能的にはunique_ptrの上位互換だから、GCではそれが用いられているだけであって。 「ナマポ禁止、スマポ使え」なC++宣教師は、 次は「漢ならunique_ptr。shared_ptrは甘え」と言うと思うぜ。 それともあれか?smalltalk的OOP或いはアクターモデル的に > オブジェクト自身に開放タイミングを決めさせる ってのか?だったらもうそれは流行らない、というか、 今のところ無駄が多すぎて普通に組んだ方がマシ、ってことになってる。 「delete忘れないようにunique_ptr使いましょーね」「共有が必要ならshared_ptrがべんりだよー」 っていうだけの話の何がそんなに気に食わないのかさっぱりわからなくてついていけない >>164 Q. 俺には必要性が分からない A. 必要がないなら無理に使わなくていいよ で済むお話。 >>164 俺は何言ってるか分かったけど、この人に説明するのは無理だろな。 使ったことがないものを批判したい感じだし、std:unique_ptrは必要になってから使えば良いよと言ってあげれば良いのかも。 まずムーブを活用して、総称性が必要になってから初めてunique_ptrを検討する感じがいいんじゃないのかな。 そしてshared_ptrは設計に時間をかけられないときに使うもので、ほとんど出番がないはず。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.4 2024/05/19 Walang Kapalit ★ | Donguri System Team 5ちゃんねる