X



C++相談室 part136
■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん (ワッチョイ bf81-LHz9)
垢版 |
2018/06/07(木) 23:40:12.36ID:GNQuDMaA0
次スレを立てる時は本文の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
0059デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 01:03:04.42ID:WzrD1lk70
>>57
起きないです。
0060はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9b6f-LHz9)
垢版 |
2018/06/10(日) 01:06:27.33ID:NuBmj+pR0
>>57
thread_local で宣言した変数は名前が同じだけでスレッドごとに違う存在だし、
それぞれのスレッドで new したならそれぞれのスレッドで配列が確保されてる。

別のスレッドの p (やそれが指す先の配列) にアクセスすれば競合が起こることは有りうるが、そうじゃないんだよね?
0061デフォルトの名無しさん (ワッチョイ 135e-JdDl)
垢版 |
2018/06/10(日) 01:11:48.03ID:z8yivKF60
>>59

ありがとうございます。これが本当ならホッとします。

でも、これって規格書に明確に記述されているのか、コンパイラがそういう仕様の
アセンブラコードを吐き出しているだけなのかわかりません。

データ競合がおきたら修羅場ですw
0062デフォルトの名無しさん (ワッチョイ 135e-JdDl)
垢版 |
2018/06/10(日) 01:14:17.08ID:z8yivKF60
>>60

ありがとうございます。

>別のスレッドの p (やそれが指す先の配列) にアクセスすれば競合が起こることは有りうるが、そうじゃないんだよね?

それはないです。
0063デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 01:21:34.27ID:WzrD1lk70
>>61
明確です。
newで確保される領域はダイナミックストレージに属します。
これは他のスレッドと同時に読み書きを行えば競合します。

thread_localで確保されたint* pはスレッドストレージに属します。
これは複数のスレッドで別のページに属します。
従って、pに対して読み書きしている分には競合しません。
0064デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 01:24:48.36ID:CUftH0/Q0
>>58
> 低レイヤを低レイヤのままで扱うスタイルを是とするものではない。
そう。で、俺は、低位はDLLで切り出しても大して問題なく、
高位だけなら他言語を使った方が効率的、という見方。

> その上のレイヤに持ち上げるときには必ずスマートポインタを使えってくらいの主張なら真っ当だと思う。
ちなみにそもそも俺はスマポ自体に懐疑的で、

・スマポじゃないとやってられないのはシャローコピーを永続化させるときくらいで、
 C++でこの使い方をすることはほぼない。
 (部分的シャローコピーでオブジェクト毎の生存期間に差が出て、
 さらにそれがデータ依存しており、プログラム側で確定させるのが面倒なとき。
 (半分満たす)例:このスレのレス配列があったとして、
 特定のIDのみ、ポップアップ用にシャローコピーで抜き出す場合。
 ただしこの場合はポップアップ後も次のポップアップ用に全体配列を保持する為、
 シャローコピーの永続化はせず、寿命管理は全体配列単位となり、スマポじゃなくても苦労しない。
 というより、正直、該当ケースを思いつけない)

なんだな。
要は、オブジェクトの生存期間をコード上で静的に確定させられないときにはスマポは強力だが、
俺には該当ケースがないんだな。
というか、お前ら何に使ってるんだ?
面倒なだけなら、GC言語の方が楽だしいいと思うんだが。
0065デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 01:30:29.54ID:WzrD1lk70
で結局ユニポでいいんだよな?
0079デフォルトの名無しさん (ブーイモ MM05-dEMp)
垢版 |
2018/06/10(日) 13:26:42.87ID:SJAMvsgqM
>>71
生存期間がシンプルすぎるからunique_ptrが入らないっていうのは賛同できないわー。
将来デストラクタが複雑になって誰かがdeleteする経路をすっ飛ばしてreturnしてしまうかもしれんし、使えるところは使っておけばいいじゃない。
何を気にしてunique_ptrさけてるの?
0080デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 13:28:20.49ID:CUftH0/Q0
>>70
それで何が嬉しいんだ?

ついでに質問しておこう。
君はCのような自前でリソース管理をしなければならない言語でリソース管理をしたことがあるか?


あと、これはC++er全般に対してだが、
shared_ptrが絶対に必要なケースってのは何だ?
unique_ptrで後述A,B以外の使い方Dがあるか?(なおCは予約語)
0081デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 13:29:15.80ID:CUftH0/Q0
Cでのリソース管理戦略は非常に単純で、おそらく以下の2つしかない。

A. 作成者が責任を持って破棄する。
B. 投げ捨て。基本的に所有権を渡し、末端(付近)で破棄する。

Aが基本パターンになる。
Bは例えば描画用の一時データ等の場合で、
この場合、使用するのは「描画ルーチン『だけ』」であり、それ以降は不要だと自明だから、
・「描画ルーチン」までの途中経路での使用は原則禁止
 (厳密には、「描画ルーチン」呼び出し以降の使用は禁止で、
 呼び出し以前は改変等を加えてもいい=この例なら、描画スケールの改変等)
・「描画ルーチン」内で必ず破棄
となる。
ただしあまり気にしないのならBも使わず、Aだけで組んでも問題ない。(というか多分そっちが主流か?)
描画の例であれば、描画終了後は普通はかなり速やかに親関数まで帰ってくるので、
親関数側でfreeするA方式でも大差ないからだ。

対して、OOP的に実装した場合、例えばゲームの敵キャラの生成/消滅を管理するとして、
この場合は「描画ルーチン」のように
「静的に明示的に生成/消滅の両方を内包する親関数」が規定出来ないので、
A方式は事実上使えず、Bで対応するしかない。だから上記を書き直せば、以下となる。

A. 「作成/使用の両方を静的に管理下に持つ親関数」を規定出来る場合、(=構造化プログラミング)
 その親関数内で確保し、親関数のスコープ終了と共に破棄する。
B. 上記親関数を規定出来ず、「作成」「使用」場所が明示的な場合、(=OOP)
 「作成」後は基本的に所有権を譲渡し、「使用」後に破棄する。
0082デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 13:29:42.93ID:CUftH0/Q0
既に言ったように、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は予約語)
0083デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 13:30:26.90ID:WzrD1lk70
例外安全性の確保でウッカリさんするくらいなら使った方が良い。
0086デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 13:35:21.57ID:CUftH0/Q0
>>68,79
そもそもpimpl自体が要らんだろ。
あれはC++のコンパイラが単純に仕様変更

・ヘッダにはprivate関数は書く必要がありません

すればいいだけの話で、そもそも「名前空間は開いていますが、クラスは閉じています(キリッ」を、
「ヘッダのクラスは開いていますが、実装のクラスは閉じています(キリッ」にすればいいだけ。

編集上の都合でソースが汚れるとか、全く馬鹿な話だろ。
気づけよ。
0089デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/10(日) 13:37:46.22ID:pLs6h5jj0
pimplに近いテクニックとしてC言語の頃から絶縁テクニックというものがあるが
それをやると大概静的解析ツールが横暴な量の警告メッセージを吐いてきやがるので却下
pimplも多分同じ結果に…
0090デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 13:39:41.44ID:WzrD1lk70
Javascriptを使って感じるC++の有利な点は仕様の明確さだろう。
Javaは重いと言われユーザーに嫌われる言語のひとつだが、開発者はベンチマークを提示しC++の20倍速いと言う。
しかしユーザーは実際に重くて困っているだろう。
ブラウザも同じ問題を抱えていて、当然Javascriptも重いとユーザーは感じている。
0091デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 13:45:01.51ID:WzrD1lk70
Microsoft社はソフトウェアの使用状況を監視させてほしいとユーザーにお願いする。
IMEの誤変換データや、プログラムのクラッシュ時の情報などだ。
これらは、開発者とユーザーの間の意識の乖離を埋める可能性がある。
ユーザーの重いと開発者の軽いのような。
オープンソースに対するアドバンテージがここにあるのかもしれない。
0094デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 13:49:25.02ID:WzrD1lk70
Visual StudioはCMakeに対応したし、Microsoft社はオープンソースとの付き合い方をやっと学んだようだ。
0096デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 13:54:17.23ID:WzrD1lk70
pimplを多用するライブラリの一つにQtがある。
C++はテンプレートによって拡張性を担保できる言語だ。
一方、拡張性はライブラリのユーザーにとってわかりやすさを損なう。
IDEとの結合において、pimplによる公開は一つのテクニックかもしれない。
0097デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 13:55:31.45ID:WzrD1lk70
ところでpimplってぽいんぷるって読むんだよな?
0099デフォルトの名無しさん (ワッチョイ d17f-LHz9)
垢版 |
2018/06/10(日) 14:01:14.71ID:O8pZIlTr0
RAIIは?
0100デフォルトの名無しさん (ブーイモ MM05-dEMp)
垢版 |
2018/06/10(日) 14:03:24.78ID:SJAMvsgqM
>>82
cで参照カウント使ってる例なんていくらでもあると思うけど。例えばキャッシュとか。
参照カウントを自前で書けばいいからshared_ptrはいらないって言ってるわけではないよね?
0101デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/10(日) 14:25:32.87ID:pLs6h5jj0
キャッシュは不意のアクセスに備える目的のやつだから
今誰もアクセスすなくなったからといって即開放(例: キャッシュラインをinvalidate)したら意味半減くね…?
というわけで、参照カウントの使用例としては不適切くね…??

それはそうとして、
資源の開放タイミングをスマポに頼るのは負けというC言語スキー氏には概ね同意だが
プログラマーが後始末タイミングをどうしても決められないシチュは存在するからスマポは要る
GCのように、開放タイミングを決めるのが未来のプログラマーなケースがそれ
0102デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 14:32:47.18ID:CUftH0/Q0
>>95
いい突っ込みだ。
今の実装だと、最低限プライベートの全サイズは要るのか。
Javaとかどうしてんだろうな?

現実的な解としては、
privateフィールドについてはコンパイラが自動的にpimpl的に間接参照に切り替えだな。
どうせpimplにする気だったのなら速度的にも大差ない。

いずれにしても、今の時代、コンパイラに合わせてコードを書くのは間違いで、
人間に合わせてコンパイラが努力するのが正しい。
0103はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9b6f-LHz9)
垢版 |
2018/06/10(日) 14:34:08.96ID:NuBmj+pR0
>>80
ワイはオッサンやで。 C++98 が出来る前から C も C++ も使ってるというか、
マイコンで BASIC とアセンブラが主流だった時代の人だで。

そのときは何にも疑問に思わなかったけど、
今どきのモダンな仕組みを知ってしまったら、
昔の牧歌的なリソース管理なんて本当にしたくねぇという気持ちなんだよ。
(かといって使い慣れたパラダイムから離れるのも面倒くさい。 オッサンなので。)

>>81-82
そこで unique_ptr を使うことに疑問を持つことが意味わからんのだが。
まさにそういう風に使うためのもんだし、
その例で unique_ptr への懐疑を説明されてももう俺には何にも言えねぇ。
0105デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 14:45:42.60ID:CUftH0/Q0
>>100
> 参照カウントを自前で書けばいいからshared_ptrはいらないって言ってるわけではないよね?
そういうわけではない。
ただ、参照カウントを自前で書いても大して苦労しないのも事実だが。


> 例えばキャッシュとか。
これはいい例に見えるが、実はちょっと違う。

まず、これは「生存期間にデータ依存性がある為、上位関数からではde.lete出来ない」例ではある。
ただ、実際にキャッシュを実装すると、

1. non_sharedのキャッシュの場合、要するにLRU判定で捨てるときにそのままdeleteすれば良いだけ。
2. shared_cacheの場合、例えばCPUのキャッシュのエミュレーションを行う場合、
 書き込みで他CPUのキャッシュを無効化するとか、その手の上位側の制御が必ず必要で、
shared_ptrだけでサクッと実装、ってことにはならない。

だから、Cで実装してもC++のスマポで実装しても、実は手間があまり変わらない。
それではおいしくないんだよ。
勿論、「書き込み無し」とかだと、破棄の制御をしなくていい分C++の方が楽に実装出来るが。
つまるところ、shared_ptrは、
手抜きデタラメ実装する場合は凄く便利だが、ガチで実装する場合にはあまり恩恵がないんだ。
とりあえず、キャッシュの場合はそう。

ってのが>>101の意見でもあると思うが。
0106デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/10(日) 14:47:27.38ID:pLs6h5jj0
>>104
キャッシュは、存在すればアクセスのレイテンシーが短縮されるというラッキーをクライアントに提供するだけのしくみ
よって、キャッシュ上のデータというのは基本いつ消してもシステムにとって致命傷にはならず、
かつ可能な限りキャッシュ上に残存するように普通は設計する
参照カウンタが0より大きいからキャッシュ上のデータを消してはいけないという法は無い

一方、仮に>>104で言いたいのがアクセスしている最中に消したらアカン、という話なのであれば、
それは排他制御の話題であってそれも参照カウントとは関係無く言える話やし…
0107デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 14:48:15.03ID:CUftH0/Q0
>>101
スマポは未来のプログラマーが解放することを「文法的に」示す意味しかない。

例えば、mallocも同様だが、
当然ナマポが返ってきて、それを解放するのは未来のプログラマー責任になっている。
要するに「そういう使い方」を規定すれば済むだけなんだよ。
0108デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 14:56:39.55ID:WzrD1lk70
unique_ptrが必要ないというのは、C++を使ったことがないってことだから、C++を使ってる人に対して、unique_ptrを使うべきでないと意見しても意味がない。
必要だから使ってるんだし。
0109デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 15:01:32.09ID:CUftH0/Q0
>>103
俺はunique_ptrは「C的リソース管理を文法的に示す」意味しかないと見てる。

反対する意味もないが、積極的に使う意味もない。
元々そうとしか組めないし、既にコードはそうなってるから。
だからunique_ptrに書き換えろってのは、相当にウザイ。
他言語だとforeachをforに書き換えろとか、あれと同じじゃないかな。

たぶんLinusもこれなんだよ。
C++の奴は新しい文法でやることに意義を感じているようだが、
それによってソースコードの構造が改善されるかというと、全くそうじゃない。
むしろ、おかしくなることの方が多いわけでね。pimplとかもそうでしょ。

> 昔の牧歌的なリソース管理なんて本当にしたくねぇという気持ちなんだよ。
これがよく分からん。
というか俺はリソース管理したくないから当然のごとくGC言語を使っているわけで、
そこまでしてC++に拘る理由が分からん。
スマポ使えというなら、うるせえGC言語使え、と返したい。
0110デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 15:08:27.48ID:WzrD1lk70
Cより開発効率が高く、Javaよりユーザーにベネフィットを提供できる。
そういった観点から、広く使われるソフトウェアの開発にC++を採用するのは理にかなっている。
JavaにしろC#にしろ、GUIライブラリがころころ変わるのは、エンドユーザーが受け入れないからだろう。
そう、馬鹿なユーザーはJavaやC#の利点を気にかけないのだ、自分のことしか考えない利己主義め!
なぜ重いソフトウェアを使うべきなのか、ユーザーをキチンと教育する必要がある。
あるいはC++を選ぶ。
0111デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/10(日) 15:19:42.39ID:pLs6h5jj0
>>107
>スマポは未来のプログラマーが解放することを「文法的に」示す意味しかない。
スマポでできて、free()ではできないことがあるからその言い分は違うくね?
いやまあ>>101でGCとしか言わなかったのは言葉足らずだったので今条件を追加するが、
こちらが実装上の都合で用意するオブジェクトの数と、未来のプログラマーに対して見せかけるオブジェクトの数が相違するケースでは
どうしてもスマポ的な手段に訴える(オブジェクト自身に開放タイミングを決めさせる)必要があるんじゃー!

例えば画像データみたいに巨大故に必要無い限りコピーしたくないんだけどそんな事情をライブラリ利用者から隠蔽したいケース
あるいは、やっぱGC自体が行う本来のガベージコレクション業務タイミングを決める方法とか、
(GCがシステムに1個しか無いのに対して、ユーザーは潜在的に多数でありGCの存在を関知せずに使ってくれる

一方、「必ずfree()せよ」という仕様には、malloc()したヒープ1個の開放以上の意味を持たせられない
0112デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 15:24:27.83ID:WzrD1lk70
std::unique_ptrを使用したくない局面では、テンプレート仮引数Allocatorを用意するべきである。
つまり、ほとんどの場合、std::unique_ptrが有用である。
0113デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 15:28:05.51ID:CUftH0/Q0
>>111
> 例えば画像データみたいに巨大故に必要無い限りコピーしたくないんだけどそんな事情をライブラリ利用者から隠蔽したいケース
なるほど理解した。
ここでshared_ptrを渡して多数に見せかけ、実は中身は一つ、という話か。

となると、当然インミュータブルでないと話にならないわけだが、
逆に言えば、今時のインミュータブルな世界にはshared_ptrが大活躍する余地があるのか?
すぐにはピンと来ないが。
0114デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/10(日) 15:33:13.30ID:pLs6h5jj0
>>113
△: 当然インミュータブルでないと話にならないわけだが、
○: 当然インミュータブルなインターフェースでないと話にならないわけだが、

実装は別にミュータブルでもクラスで覆うならやりようはいくらでもあるんじゃ…
画像の書き換えを専用メソッドでやるか、あるいは速度優先でcheckout/checkin式にcheckout中だけ直接アクセスを許すとか、
(もちろんcheckout時にコピーを行う

で、内部ではshared_ptr(的な、「オブジェクト自身に開放タイミングを決めさせる」)ロジックが大活躍!!111!!!!1!
0116デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/10(日) 15:35:49.57ID:pLs6h5jj0
訂正;
×: あるいは速度優先でcheckout/checkin式にcheckout中だけ直接アクセスを許すとか、
○: あるいは書き換え速度優先でcheckout/checkin式にcheckout中だけ画像への直接アクセスによる書き換えを許すとか、
0118デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 16:02:15.14ID:CUftH0/Q0
>>114,116
まあ分かった。
多分shared_ptrは『ほぼ』インミュータブルな世界とは相性がいい。
(ミュータブルにする必要がほぼなく、その場合は明示的に別メソッドを呼んでもいい場合)

つっても適用事例はWebサーバーくらいしか思いつかない。
ある画像が人気でユーザーが一斉にダウンロードしたとして、
鯖内部に30秒間だけキャッシュする場合とか。

ナマポで渡した場合、各ユーザーのダウンロード完了でカウントを減らし、0になるまで破棄出来ない。
shared_ptrで渡した場合、30秒の期限が過ぎればキャッシュから破棄しても問題ない。
この辺は確かに楽に組めるようになる。
0119デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 16:07:24.50ID:WzrD1lk70
>>118
キャッシュにstd::shared_ptrを使用するのは愚策すぎるのではないか。
実のところstd::shared_ptrはほとんど出番がない。
設計を練れば練るほど出番は失われていく。
0120デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/10(日) 16:15:05.15ID:pLs6h5jj0
いやすまんインミュータブルなインターフェースといいつつ>>114では画像を書き換えるインターフェースの話をしてしまったスマンorz
「画像の書き換えを専用メソッドでやる」は、「加工後の画像を専用メソッドで生成する」、と読み替えてホスイ

で、ライブラリが画像Aを生成し、その画像がライブラリのユーザーによって不特定多数のクライアントとのセッションスレッドに渡されるシチュを考える
セッションスレッドの具体的な数は事前にはわからない。(接続してくるクライアント次第
また、何らかのタイミングでクライアントに提示すべき画像Aは、別の画像A'に差し変わる。

ライブラリのユーザーとしてはスレッド間の排他制御に関して面倒な問題を抱え込むのは嫌なので、
メインスレッド(セッションスレッドを起こす)から、画像Aのコピーを、所有権を譲渡する形でセッションスレッドに渡す、という使い方をする。・・・(1)

ライブラリ内部では、(1)の使い方をされるときにいちいち画像Aをコピーしたりしない。

画像Aの開放は、画像AがA'に差し変わるタイミングで行いたい。
ただし、画像Aを使っているセッションスレッドが居る間は開放するわけにはいかない。
しかし、当該スレッドがセッションを終えるのを待っていたら、新規につないで来るクライアントへの画像A'の提示が遅れる

→画像Aの開放タイミングはスマポで解決!
0121デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/10(日) 16:27:25.23ID:pLs6h5jj0
>>118
ちょっまだキャッシュ言いますかキャッシュと参照カウントは原理上無関係なので(>>106)忘れてよろしいかと、
(参照カウンタが0より大きいからキャッシュ上のデータを消してはいけないという法は無いし、
 参照カウンタが0になったからといってキャッシュ上のデータを消さなければいけないという法も無い

Webサーバというのは適用事例として好適だがダウンロード中かダウンロード完了か、という区分でしか考えないのはイクナイ
ダウンロード中にも新規のクライアントがつないでくるかもしれない
そのときダウンロード完了時に画像を破棄すればいいやという単色の思考だと、新規のクライアントが繋いで来つづける限り
画像を永久に開放できないことになり、そればかりか>>120のように、画像をAからA'に差し替えることもできない

これは画像Aの開放を、画像Aのオブジェクト自身に面倒をみさせるしかない(自身を参照するセッションスレッドが0になったとき開放させる
サーバはそれとは並行して画像A'を新規のセッションスレッドに展開できる。
こんな芸当ができるのはスマポだけ!
0122デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 17:11:42.47ID:CUftH0/Q0
>>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を使っても大して楽にはならない)
0123デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 17:28:14.89ID:CUftH0/Q0
一応簡単に俺の主張を纏めておくと、

・unique_ptrは従来C方式を文法的に強制させるだけで、コードの改善には繋がらない。
・shared_ptrの使いどころはWebサーバーしか思いつかない。

GC言語は基本的にshared_ptrなわけだが、あれって基本的に手抜き専用で、
GCがないと本質的に辛いって構造はあんまりない。
Rustも今更GC無しですかー、とも思うが、実際、無しなら無しでもいいか、程度ではある。
0126デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 18:04:27.80ID:WzrD1lk70
std::enable_ifを使いこなそう。
0128デフォルトの名無しさん (ワッチョイ 09c3-5Ttc)
垢版 |
2018/06/10(日) 18:05:45.54ID:k6CFzDb+0
「バカよけ」機能に価値はない、無駄だから使わないしコードが長くなるから使わせない
っていう老害いるよね
そういう奴に限ってバグや脆弱性作り込むんだけど決して反省しない
0129デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 18:06:37.55ID:WzrD1lk70
std::unique_ptrを導入すると人事部から一人削減できるってことじゃないか。
0130デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 18:09:53.52ID:WzrD1lk70
まともな知的生命体なら迷わずユニポを使うだろう。
0131デフォルトの名無しさん (ワッチョイ 3139-LHz9)
垢版 |
2018/06/10(日) 18:21:28.47ID:E4gfPCgl0
>>128
まあ俺も老害とか言われることのある世代だが
価値がないのは「バカよけ」ではなく「バカ用」な
バカなふりをする達人をニヤリとさせるのではなく、
どうしようもない真性バカを延命する機能は有害なだけ
0134デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 19:42:24.37ID:CUftH0/Q0
混乱を避ける為に先に質問しておきたいんだが、
上記A(82)の場合、つまり、
親関数から子関数にポインタを渡したいが、所有権を移動しない場合には、どう書くんだ?
ざっと探しても出てこないんだが。

引数に値渡ししたらムーブ、これは分かる。
ムーブしたくないが子関数に渡したい場合は?
0136デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 19:45:27.08ID:CUftH0/Q0
>>124
それはありだ。

ただし、俺は「循環参照の場合に回収出来ないGC」であってもいいと思っている。
循環参照が必要なケースはほぼ無いので、明示的に切ってから解放でいい。
これはweak_ptrと同じで、C++erなら同意してもらえると思う。

ついでにいうと、「コンパクションが出来ないGC」でもいい。
これなら**ptrにする必要なく、*ptrで行けるから速度低下も起きない。

つまり、仕様はC++どおりでいいが、
プログラマにやらせるな、自動でやれ、ということ。俺的には。
0137デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 20:15:37.49ID:lEW5NtSH0
>>135
なんだよ!所有権の複製もできないのかよ!?
やっぱりstd::unique_ptrダメじゃん!!!!
0138デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 20:21:31.52ID:CUftH0/Q0
>>137
まあそのネタはさておき、マジで探しているのだが出てこない。
知ってたら教えてくれよ。

これ、もしかしてget()してナマポ渡すしかないとかいうオチ?
ならunique_ptrなんてマジでゴミだぞ。
さすがにそれはないと信じて探しているのだが、マジで出てこない。
0139デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 20:22:18.03ID:lEW5NtSH0
>>138
参照で渡せばいいんじゃないのか?
そんなことして何の意味があるのか知らんが。
0140デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 20:23:52.60ID:lEW5NtSH0
std::unique_ptrに対するweak_ptrは無いぞ。
だからゴミだという場合は、>>137
0141デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 20:24:48.73ID:CUftH0/Q0
>>139
俺も最初はそうかと思っていたんだが、実はそれも出てこないんだよね。

まあでもそれで、コンパイラが最適化をするのを期待する、というC++的オチか?
これはあり得るとは思うが。
0142デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 20:28:59.72ID:lEW5NtSH0
>>141
当たり前すぎて出てこないだけでは?
auto result = my_func(*my_unique_);
とすればいいだけなんじゃないの?
0143デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 20:31:55.61ID:lEW5NtSH0
std::unique_ptrを利用する主な動機は総称型を保持するためなんだよな。
0145デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 20:37:44.47ID:lEW5NtSH0
>>144
lvalue_referenceだから仮引数側でどうにでもできるだろ。
0146デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 20:49:11.93ID:lEW5NtSH0
https://ideone.com/SEcQKq

こういうことがしたいんじゃないのか?
0148デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 21:22:56.11ID:CUftH0/Q0
>>146
だから違うっての

>>147
多分俺が欲しいのはそれだ。
https://en.cppreference.com/w/cpp/experimental/observer_ptr
要するに、「ナマポだがdelete出来ない物」が欲しい。
unique_ptrは値渡しすると所有権が移動してしまう。
関数にはポインタの場合値渡しが最速だし、自明だから、グダグダ書いて最適化を待つ、とかやりたくない。
生成は常にunique_ptrからの値コピー(所有権は移動しない)でいい。

寿命管理は他に任せるが、ナマポと完全に同パフォーマンスの物、これが欲しい。

まあ、検討中ならよかった。
0149デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 22:03:51.04ID:lEW5NtSH0
deleteされたくないポインタと言えばこうだろ。
https://ideone.com/PvzDVY
0150デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/10(日) 22:50:21.29ID:CUftH0/Q0
>>125
> 漠然としてたものに区別を与えてくれる最高の機能じゃんね。
俺の理解が正しければ、これはダウト。表現力が足りない。
今のunique_ptrはB用のインタフェースしか持っておらず、Aを最速では記述出来ない。
足りてないのは、既に言ったとおり、「ナマポと同速だがdelete出来ないスマポ」。

だからやっぱイマイチなんだな。
とはいえ確実に拡充されてるから、最終的にどうなるかは見物だが。
高位機能も最終的には追いつくだろうし。

ただ、C++はプログラマの努力で何とかしようとしているが、
そもそもAにしてもBにしてもコールグラフの解析でfree忘れとか抜けるはずなんだよね。
Cの連中はこの辺には興味ないみたいだけど、
人手でやってる分、スマポみたいにコーナーぎりぎりを攻められないから、
ある程度わかりやすいところでfreeされてる。
当然、ツールにもかかり易いはずで。
0151デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 23:09:19.21ID:lEW5NtSH0
それ参照でいいだろ。
言ってる意味が全く分からない。
0152デフォルトの名無しさん (ワッチョイ b1a9-uWQQ)
垢版 |
2018/06/10(日) 23:41:15.51ID:IWNTecyr0
私もはやく皆さんとお話したいのですが、内容が全くわかりません。
C++でRPG作れる程度の知識なのですが、何から学べば良いでしょうか。
おすすめの本、サイトがあれば教えてくださいが
0154デフォルトの名無しさん (ワッチョイ 81b3-8neN)
垢版 |
2018/06/10(日) 23:47:37.76ID:lEW5NtSH0
そりゃC++使ってる人が読んだって全く分からないだろうな。
0155デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/11(月) 07:09:55.61ID:ekbt9EBF0
>>122
>1. インミュータブルなインタフェースで、
>2. 不特定多数がランダムに掴みに来て、
>3. 解放タイミングがユーザー依存で読めない場合
ちゃうねんそれでは表層的な観察にすぎなず、
shared_ptr(的な、「オブジェクト自身に開放タイミングを決めさせる」(>>114))処理の必要性の1断面でしかないねん

>>121-122が言っているのは、
>こちらが実装上の都合で用意するオブジェクトの数と、未来のプログラマーに対して見せかけるオブジェクトの数が相違するケース(>>111)
において、未来のプログラマー(ユーザー)がオブジェクトをコピーしたつもりだが実装の内部ではコピーしていなくって、
ユーザー視点では自身のプログラムが保持する独立した1オブジェクトを開放したつもりが、実は内部の実装の都合において、
ユーザーまたはユーザー2のプログラムが保持する別のオブジェクトの開放と関係を持ってしまうケース(∵実体が同一)において
shared_ptr的な、「オブジェクト自身に開放タイミングを決めさせる」(>>114))処理が必要ということなんじゃー
0156デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/11(月) 07:23:54.00ID:ekbt9EBF0
.>>122
>画像の差し替えはキャッシュ内の画像Aを無効化することにより行われる。
これは>>121のケースでは問題の解決にならない。
なぜなら、仮にキャッシュ上に画像Aを用意してあり、最後まで画像Aを掴むことになったセッションXに対して
セッション開始時にメインスレッドが渡したのがキャッシュ上の画像Aだったとしても、
渡した瞬間にセッションとキャッシュの関係は切れるからじゃわ!(半切れ

>>121は、セッションXは自身のローカル記憶(のつもり)であるところのオンメモリの画像Aを使い、
セッション終了時に開放する、ということしか言っておらず、
セッション中に2回3回とキャッシュ上の画像Aを取りにいくとは書いては
いない
キャッシュとセッションXの関係がセッション開始時の一瞬でしかない想定な以上、
画像Aの実体の開放に関してキャッシュの無効化機構をどう別実装しても無駄。問題に影響無し。
0157デフォルトの名無しさん (ワッチョイ 13bd-T1fc)
垢版 |
2018/06/11(月) 07:43:46.07ID:ekbt9EBF0
ちな「キャッシュの無効化機構」とは、新規セッションに見せかける画像をAで無くすしくみという意味であって(それ以外の読み方をせよというのは_)、
画像Aの実体の開放とは関係ありませんからぬ、
というわけで繰り返しになるが画像Aの実体の開放に関してキャッシュの無効化機構をどう別実装しても無駄で、
画像Aの実体の開放はshared_ptr的な、「オブジェクト自身に開放タイミングを決めさせる」(>>114))処理の専任事項となる
>>121の想定のように画像Aが複数に見えることもあるが実体は唯一、というときはそうする以外画像のAからA'への差し替えは_
0158デフォルトの名無しさん (ワッチョイ d19f-NuDx)
垢版 |
2018/06/11(月) 22:46:31.97ID:aD4/YLZg0
>>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)
でしかない。
勿論それが許容されている世界であり、スループットを取っているだけだからそれでいいんだが。
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況