C++相談室 part157
レス数が1000を超えています。これ以上書き込みはできません。
前スレの >>997
キューが溢れないようにするのなら
スレッドが実行中かどうかを確認するのではなく
キューサイズを見るほうが確実じゃないですか? >スレッドが実行中か確認したいってどんなときなのかな?
たとえばゲームでセーブするとき、
メインの処理はブロックしたくないので別スレッドで実行しつつ「セーブ中です」みたいな表示を出し、終了したら消す
みたいな時かな >>3
それはセーブするスレッドのほうが開始と終了を通知すればよくない?
そうデザインするもんじゃないの?
できないときもあるのかもしれんが。 >>4
もちろん方法ならいくらでもあると思うけど、別スレッドのインスタンス1つで全部済むなら、そっちの方がすっきりするし楽でしょ >>4,5
あぁ、いやそうじゃないか
ゲームのあらゆる部分をスレッドセーフで設計すれば良いのかもしれないけど、
ゲームのメインの状態遷移なんてわざわざマルチスレッド化するような重い処理でもないので、
その辺の表示とかはシングルスレッド前提で書いてるわけよ、もちろんそのほうが楽だからw この「実行中」が実際にタイムスライスが割り当てられている状態を意味しているんであれば
OSにもよるが実装が大変な割に実際に役立つシーンは限られるような。
>>4であればjoinableで十分だろうし。 別スレッド処理の進捗を他スレッドから閲覧するためのパラメータを使っってる時点で、お察し 前スレ997は色々勘違いしてそうな気がする
普通pushしようとしてキューが満杯なら何らかの同期メカニズムで自分を待ち状態にする
pop側はpopしたらその同期メカニズムに対して待ちを解除するだけだからスレッド自体が実行中かどうかなんて見る必要がない 正直いって pthread の条件変数は私には理解が難しく、私は安易に win32api のクリティカルセッション&シグナルを多用してしまうのです
ただし、スタベーションに陥ることが多々あり、どうもクリティカルセクション・シグナルでは駄目なパターンがあるかもしれない、とヒヤヒヤしています‥‥ >>2
別に
Producer(pushする側)がこれからpushするのを待っている場合、
Consumer(popする側)はキューサイズ(キューの中の要素数)を見ても
Producerが待っているのかどうかの情報を得られない
なぜなら、まだpushしていないからな >>9
>pop側はpopしたらその同期メカニズムに対して待ちを解除するだけ
そういう実現方法も(pop側が行った待ち解除がキューイングされれば)成立する鴨、と>>997にちゃんと書いているもーん >>5
>>4って新規スレッド1個で全部済むと思うんだけど…… >>13
いや、スレッドの実行状態なんて見てもしゃーないって話
pop後にpush側が実行中だとしてもそのチェック直後にpushするかも知れん
要するにスレッドの実行状態の変化は排他制御できないから意味がないって話
pop前にいちいちスレッドをsuspendしてチェックしてからresumeするとかするならできるかもしれないけどw std::vectorの部分ベクトルの切り出しって絶対O(要素数)の計算量かかりますよね? こういうの?
std::vector<int> a{ 4, 6, 4, 9 };
std::vector<int> b(a.begin() + 1, a.begin() + 2); 参照できればいいのか、コピーがいるのか、切り出し位置はわかってるのか、検索を伴うのか、
その辺の条件もなしに計算量の議論なんて出来んわ クラスAの内部にクラスBがある (入れ子クラス) として、BからAのメンバにアクセスするテクってないんですかね?
アクセスしたいメンバをstaticにはしたくないです >>20
AへのポインタをBに定義して、コンストラクタかなんかで渡せばいいのでは? >>20
クラスの中でクラスを定義しても A の名前空間の中に B が定義されるってだけ。
B のオブジェクトを作っても A のオブジェクトが存在しないなら存在しないオブジェクトのメンバにはアクセスできない。
A のオブジェクト (インスタンス) と B のオブジェクトの間には勝手に関係が出来たりもしない。
関係ないのに関係あるように見えて初心者が混乱してるのはどっかの質問サイトでも見たことがある。
よく理解できてないならまずはクラスの定義を入れ子にせずにやってみるのがオススメ。 >>20
AやBのインスタンスをどう生成してるのよ
>>21の言うようにAへのポインタ持ってたら普通にアクセスするだけでしょ
class A {
public: int i;
class B {
public: B(A* a){ … = a->i; }
}
}
…
auto b = new A::B(new A()); >>19
コピーか参照かは1要素あたりの処理量なので
コンテナの計算量には関係ない 絶対レビュー通らないウンココードでよいなら
(char*)this + offsetof(A, b)でなんとかならんのか class Aをtemplate化して、class BでAを継承すれはメンバにはアクセスできるけど、たぶんそういうことがしないんじゃないんだろうなw
コンテナクラスのイテレータから親クラスインスタンスのメンバにアクセスしたいとかか? リファレンサを作るときなんか親オブジェクトへのポインタ使うね >>23
普通にコンポジションで実現できる条件だよな
メルプラネットの奴らも同じこと言いそう 親オブジェクトへのポインタをうっかり共有ポインタにすると循環参照の原因になる(小並感) +=の引数が1のときは++を呼ぶようにする方法ってありますか >>30
自分でそう書くのがいいのでは?
(n == 1) ? x++ : x += n; >>30
遅くなる可能性があるから気にしない。
コンパイル時に解決できるなら++使っても同じだし、実行時に解決するようだと1かどうかの判定が増えて遅くなる。 TCPIPのソケット通信プログラム作ろうと思っているのですが、
コネクションを維持し続ける場合のデメリットって何がありますか? >>32
後出しになって申し訳ありませんが、*、!=、++、+=、- 辺りが定義されたイテレータを持つ自作のデータ構造を範囲for文で走査することを考えています
それ自体は想定した通りにできたのですが、その範囲for文をomp並列化するとイテレータのインクリメントが ++ でなく +=1 で行われるようになります
で、その自作データ構造では ++ よりも += の方が重い実装になっているので、+=1 よりは ++ の方を使ってほしいです
omp に特有の仕様に思えるので、普通に += の冒頭で引数が1かどうかの分岐を入れることにしようかと思います
ありがとうございました マルチスレッドのキューのサンプルをSTLで作りゃったーしたったわ、
https://ideone.com/bS7rqc
↓ここのC#のサンプルプログラムの移植
// https://atmarkit.itmedia.co.jp/ait/articles/1801/31/news023.html
フラグの必要性は意味を取り違えていたわサーセン、
しかしこれフラグ(runningFlag)無しでやるとしたら終了時にConsumerがいちいちProducerが
join可能か調べる(std::thread::joinable())ことになってスレッドより先にプログラムした人が終了したくなるお
フラグで済むのに、 と思ったがやっぱ当初の意味(Producerが待っているのかどうか)のフラグが無いと、
キューが空になった後のnotifyで、1万個あるかもしれない仕事の無いConsumerが次々起床され、
巡り巡ってようやくProducerが起床されるみたいな非効率が生じる余地があるやんけ;;;
やっぱ当初の漏れのフラグ必要という意見で正しかったのかもしんない
漏れは天才なのかもしんない、
かもしんない運転、 つかその前に、漏れの天才eyesが改造元とした@IT様のサンプルプログラムに
スレッドのディスパッチ依存で終了できなくなることがあるという恥ずかしいバグを発見した、
論より証拠:
https://ideone.com/NbKdEQ
変更点は、Consumerを1個にして、Producerの側のある個所にsleepを入れただけ
(マクロ CAUSE_STOPPING_FAILURE_BUG で条件コンパイルで有効にしている個所
これでConsumerスレッドが終了できなくなる
対策は、同ソースコードの BUGFIX_STOPPING_FAILURE_BUG マクロを有効にしたら宜しい
天才の判断である >>34
すみません。この件なんですが、
void operator += (int n){
if(n == 1){
// ここ
}else{
……
}
}
「ここ」で演算子++を呼びたいときってどう書いたら良いでしょうか
++の中身をコピペしても良いのですが、
this -> ++
みたいなノリで呼び出せた方が都合が良いです というわけで最終的な版を貼る、
https://ideone.com/G3XeAg
ProduceとConsumerそれぞれに対する起床条件を分離すた、
日本語ではいくら説明しても一向に理解の光が射さなかったボンクラ学生レヴェルの>>15でも
100行足らずのソースコードなら読めるんじゃないの
知らんけど >>39
++(*this);
または
this->operator++(); >>41
ありがとうございます
前置/後置の別が自分の中でよく付いていませんが、教えていただいたことに基づいて調べてみます >>40
で、そこで取れると良い「スレッドの実行状態」って結局何なん? 「スレッドの実行状態とは起こす対象のスレッドが具体的に何をしているか、や
とれると良い、ではなく取ることが必須や
なぜなら、WIN32APIのイベントは1回だけキューイングされるので投げたら投げっぱなしでもそのうち
受け取ってもらえるが、(pthread系統のしくみである)状態変数はそうではなく、
起床信号を投げつける前に相手が信号をキャッチ可能なのか(待ちに入っているのか)知る必要がある
なお、イベントのキューイングの有無によって話が変わる旨はすでに書いたある(>>997
上記のことを書いてあるというのに理解もせずにしつこく同じことを繰り返し言ってきたのが>>15 >「スレッドの実行状態とは起こす対象のスレッドが具体的に何をしているか、や
それって具体的にどういうものを想定しているんだろう。
もともとの話はstd::threadに追加したい機能だったと思うけど、この説明だけじゃ全然想像がつかない。 なんか元にしたコードにまだ問題があった気配orz
MAX_QUEを1にすると高い頻度でProducerとConsumerが両方待ちに入ってしまいハングアップする、、、
対策版は多分これ↓で良いんジャマイカ……
https://ideone.com/at7ef9
(何が起きていて、どうしてこれで対策なのかはコメント参照、
>>45
>>「スレッドの実行状態とは起こす対象のスレッドが具体的に何をしているか、や
>それって具体的にどういうものを想定しているんだろう。
今回のサンプルコードでは具体的にはありません(キリ
しいて言えば!runningFlagならConsumerが自身を待ちに入れない(∵Producerがもう起こしてはくれない
というのはあるが、>>35に書いた通りフラグ以外の方法でも同じ判定を行える
言っていることにブレがあるのは今日pthreadを勉強したばっかりやし、
天才なので大目に見てホスイ、 でもまあコメントを読んでいただければ、pthread系のしくみだと
起こす対象のスレッドが何をしているのかについて常に配慮が居るということをご理解いただけるのではないかと思う
今回はたまたま見込みでnotifyして話が通るからスレッドの実行状態を表す変数が具体的に生じなかっただけ すみません。
自作プログラムが特定のPCだけ同じ場所でntdll.dllのエラーで止まるのですが、何が原因と考えられるでしょうか?
他のPCでは問題無く進み、エラーを起こすPCのメモリにも異常は見つかりませんでした。 >>48
未初期化変数があって無効なアドレスにアクセスしたとかじゃね
確実なことを言うためには例外コードが知りたい
あと問題の箇所のソースコードも ソースはすみません、ちょっと出せないです
エラーコードは0xc0000005でしま はいメモリアクセス違反ですね
デバッガでがんばって調べてね 他の言語にはスレッド実行中か判定するAPIあるしstd::thread作った人達だってそのくらいのこと知ってたでしょ
boost::thread時代にそういった要望もあっただろうし
それでもあえてstd::threadにはスレッド実行中を調べる機能を付けなかった
本質的に必要な機能ではないと判断したんじゃないの? スレッドそのものの終了状態を知る需要はあまりなく、スレッド内で行われるユーザー定義処理が終わったかどうかが重要だからでしょ >>47
>起こす対象のスレッドが何をしているのかについて常に配慮が居るということをご理解いただけるのではないかと思う
それがwaitで待っている状態かそうでないかを意味しているんだとしたらそれは正しくない。
チェックした次の瞬間にwaitする可能性もあるわけなんで。 >>55
>チェックした次の瞬間にwaitする可能性もあるわけなんで。
無い
チェックと処置をmutexによる単一のロック期間の中でアトミックに行うのだから>>55は全くナンセンスな問題提起
>>53
thread::joinable()があることは書いたもーん 問題だらけだった@IT様のサンプルコードだけど
これまともに実装するとしたら条件変数をConsumer x NとProducerの計N+1個設けて、
さらにConsumerそれぞれが待っているのか動いているのかを示すフラグを設けて
全部動いていたらProducerを待たせる
Consumerが待ちに入る直前にProducerにnotifyかけてキックする、みたいな
スレッドプールを手で実装するみたいな話になりそう……
でここまでやるならConsumerの状態変数が実体としてコードに現れる 何を主張したくてごちゃごちゃ言ってるのかさっぱり見えないし途中で変わったりしてるようでもあるので、
続けるならそもそもどういう主張をしているのかいっぺんまとめてほしい。 >>56
std::threadから取得する「スレッドの実行状態」の話をしているんだが。
それをmutexでアトミックに操作する??? iPhone専用でいいなら、そもそも、Appleが提供している標準開発環境だけでも
C++で作れる。
iPhoneの標準開発言語はSwiftだが、SwiftはC++と相互に呼び出せるから。
ただし、それだけだと面倒かも知れない。
そういう場合は、Qtで作れば。 std::vector で insert するとき
v.insert(v.begin() + n, hoge);
とかすると思いますが
このときの n の型って何ですか?
int ?
unsigned long ?
size_t ?
あとこういう型を調べるときって
vector のどことか iterator のどこを調べると判りますか? 22.3.11 Class Template vector
23.3.11.1 Overview
3
using iterator = implementation-defined; //see 22.2
となっていて、std::vector::iteratorの型は処理系定義だね
現物で調べるならVisual Studioの[F12]が簡単だと思う >>59
ID:W7aMf5pX = ID:qkzYmFIh はスレッドの状態として
・その瞬間の状態: Run/Ready/Wait/...
・終了してるかどうか: thread::joinable で取得できる
を混同してる(わざとかどうかは知らんが)
あと条件変数とスレッドの状態も混同してるので
> チェックと処置をmutexによる単一のロック期間の中でアトミックに行うのだから
なんて意味不明なことを言い出してる
これ以上続けるなら>>58が言うように本人にまとめてもらわないとますますグダグダになるだけだと思う std::thread使ったことないから自信無くて黙ってたけど
thread::joinable()って別にスレッドが終了したかの判定ではなくない?
他スレッドでの実行を管理していない状態の(空の)オブジェクトが作れるから、そういう空の状態かどうかの判定関数であるように読めた
fstream::is_open()的な…… >>63
暗黙変換があるから n の型としてはすべての整数型があり得る。
基本的には、生ポインタで実装される可能性もあるものなので ptrdiff_t だと思っておけばいい。
正確な型が必要なら difference_type とか iter_difference_t とかで調べればわかる。 >>66
> thread::joinable()って別にスレッドが終了したかの判定ではなくない?
もちろん正確にはスレッド変数がスレッドと関連づいてるかどうかの判定
彼は>>35辺りでスレッド終了判定と思い込んでるフシが見られるのでそう書いてある >>67
ありがとうございます
>>64
>現物で調べるならVisual Studioの[F12]が簡単だと思う
それで判るのは自分で定義した可能性の高い n の型ですよね?
知りたいのは v.begin() + n に要求されている型のことです >>68
やっぱりそうですよね
じゃあ>>65の2個目の中黒の内容については引用??
例のコードではjoinableなんか使ってないし>>7が書いたのを試しもせずに真に受けた感じなのかな >>69
v.begin().operator+(n)とでも書き換えてoperator+で[F12]しろということではなかろうか >>69
ランダムアクセスイテレータには difference_type (またはそれに暗黙に型変換出来る何か) を足すことができて、
その結果の型はイテレータ自身と同じ。
https://timsong-cpp.github.io/cppwp/n3337/random.access.iterators >>66
>thread::joinable()って別にスレッドが終了したかの判定ではなくない?
実際にそのスレッドが実行中か待ちか終了しているかを表しているわけじゃないことはその通り。
で、たぶんそれで十分だからjoinable以上の機能は用意されなかった。
ところがそれが役に立つ場面があるよと言ったのが前スレ>>997
このスレの>>35と同一人物かどうかは知らんが。 char *mystrcat(char *a, char *b)
{
// a に b を結合して
return a;
}
みたいな関数を
shared_ptr<char *> mystrcat(shared_ptr<char *> a, char *b)
{
// a に b を結合して
return a;
}
みたいな実装にするとき参照カウンタが無限に増える心配はありますか?
shared_ptr<char *> mystrcat(weak_ptr<char *> a, char *b)
の方が良いのでしょうか?
あと
hoge = mystrcat(NULL, hage); みたいに使用されるときは
mystrcat の中で new してコピーして new したポインタを返したいのですが問題ありませんか? >>75
shared_ptr<char *> だと、たぶんやりたいことはできてない。
shared_ptr<char[]> の間違いなんだろうと思うけど、この時点でコンパイルすら試してないのが見て取れる。
参照カウンタの動きは挙げられたソースだけじゃ読み取れないけど、無限に増えるなんてことはまず起こらない。
shared_ptr の use_count() で取れるから試してみればいい。
問題があるかどうかも自分で試してみればいい。何を「問題」とするかこちらにはわからないし。 個別の事例で心配ない、問題ないという返答を得たとしても理解が深まらない。
shared_ptr のメカニズムを理解できないと何度でも心配になるだけ。
どういう理屈で参照カウンタが無限に増えると思ったのかを説明してみて。
考え方に間違いがあれば指摘するよ。 char *mystrcat(char *a, char *b)
{
// a に b を結合して
return make_shared<char []>(a);
}
じゃいかんの
しらんけど 適当な質問者と適当な回答者
ゴミとゴミをあわせてもゴミはゴミ shared_ptr<char []> c(a);
return &c[0]; namespaceってどのように使うものなんですか?
存在意義がわからない。 >>81
大規模ライブラリを設計するときに重宝する機能
詳しい経緯は知らないがグローバルスコープの識別子名の競合を回避する目的で導入されたと思う
namespaceがないC言語時代にいくつからの大規模ライブラリを組み合わせたときに何が起きがちだったか知っていれば納得出来るはず
どんな機能もそうだが、自分が必要と思った時に使えば良いだけだよ
存在意義が分からないならお前にとっては必要のない機能ということだから、気にする必要はない Cにnamespaceが導入されないのは何故なんです? >>75
蛇足だけど、理由がなければshared_ptr<char[]>の代わりにshared_ptr<str>にしたほうがいいな。
// a に b を結合して
return a
がすごく怖い。 >>83
namespaceを導入するということは :: だのマングリングだのADLだの色々付いてくるからな >>83
マングリングが必要になってしまうから、ってのが大きいだろうな。 C++を本格的に学ぼうと思って本を数冊買ったが、言語仕様が複雑な割には知らないとエラー起こすだろ
っていう項目が多くてビビってる。あと、きれいなコードを書くのに尋常じゃない経験が必要なんじゃないか 全部知らなくてもわかる部分だけでまあまあ使えるというのが C++ の方針なので
最初から綺麗に書こうと思わないほうがいいと思う。
綺麗に書けないと考えるより汚くても普通なんだと考えると気が楽でしょ。 構造体の中に関数が書ける、というコアの中のコアな部分の使い方・考え方さえ憶えるというより慣れれば
あと他のは追加で憶えればいいってだけ
ただし、その追加が今とんでもない量になってて
禿本の初版からやってる俺でさえ憶えきれなくてもがいてる いいかい学生さん、 他人のコードをな、 他人のコードをいつでも読めるくらいになりなよ。
それが、人間えら過ぎもしない貧乏過ぎもしない、 ちょうどいいくらいってとこなんだ。 >>88
エラーが起こったらまだマシだな
イクときはだまってイクからな 他人のコードを読んで学ぶのに一番向いてない言語だよなC++は。 perlは文法が複雑なだけで、知らない書き方に出会ったらそれを調べればいい。
C++はコードの断片だけ見ても動作を想像できないことがあるから厄介。 スマートポインタに慣れたら自分で解放しなきゃならないmallocやnewの方がよっぽど面倒 autoが便利すぎて反復子の型を明示していたころのC++には戻れそうにない QZ案外初心者やなw
でも言ってることは全面的に賛成
ポインタや参照、クラス等の基本を抑えてからでないとスマポや、C++11からの要素(右辺値参照含む)の使い方もわからんと思う autoもそうだが ->戻り型やusingエイリアスもだね
typedefには戻れない >>103
確かに罰ゲームの一種になるかも‥‥私も少しずつ採り入れていくようになっていますし
>>104
もう永遠の初心者だと思っていますので、ならば、初心者の気持ちがわかるコメントでコントリビュートするのもありかと、ふつふつと >>104
なにこれ?
QZ「〜」
名無し「QZ初心者やな。でも賛成」
っていう自演をやろうとしたが、一個目のQZのレスをコテつけ忘れで投稿してしまったのか?
あるいははちみつとQZを同一視している?
いずれにせよとんでもない皮肉だな笑 >>107
いちいち反応しなくてもよろしい
>>108
つ鏡 >>107
それ、以前俺が書いたカキコを勝手にコピペされただけだよ クッソささやかな体面保つためだけの自演も失敗とか本当にみじめないきものだな… >>111
ブラウザが記憶してたのを再度投稿してしまったとかそういうしょうもないミスじゃないかな。
JaneStyle のメモ欄で以前のレス内容を貼り付けたりそのまま投稿できたりする機能があるよ。 だから勝手にコピペされたっつってんだろクソ餃子め
>>104は俺じゃないから
3行目を引用したかったのか変な自演したかったのかは知らん >>113
すまぬ。
本人によるものでなくてもなんらかの意図でメモしてたものを
うっかりということは起こりそうなデザインにはなっているので、
意図によるものでなくただのミスじゃねという部分が主旨。 >>116
現時点でこのスレにコテ (+トリップ) 付きで書き込んでいるのがはちみつ餃子と QZ だけだからだろ。 (unsigned) intの数を受けたら何らかの演算をして (unsigned) long longの数を返す、(unsigned) double の数を受けたら何らかの演算をして (unsigned) long double の数を返す、みたいのって逐一オーバーロードを書くしかないですよね?
要するに、大きいデータ型に格上げして何らかの演算をして返したいってことなんですが >>118
演算子のオーバーロードにしても関数のオーバーロードにしても、返り値の型を指定することは出来なかったかと
思いつくのは演算前の引数にあてがうキャストのオーバーロードですね 引数をテンプレートにして、引数Tのビット数と整数型かどうかを見て、一段階大きい型を戻り値の型とすることは出来る >>120
pls kwsk
>>119 普通にコンストラクタのほうがいいですか‥ ごめん、めんどい・・というか
sizeof(T)と整数or浮動小数点数のbool(is_integralとかで取る)を受け取る構造体の中でtype(戻り値の型)を定義、とか考えてたけど
結局Tのサイズごとに特殊化するから手間変わらん、てのと
関数の中身が長くなるなら、オーバーロードした関数からテンプレート版(戻り値の型と引数の型がテンプレート)を呼んで、そこで中身書けば一回で済むね >>118
ふつうに long long や long double を引数で受け取るって演算して返す関数を書けば
その通りの動作になりそうなんだけど、何か気に入らないの?
2つ関数書くのが嫌だってこと?(やりたいことが少なくとも2通りあるのに?) 大きい型というのは一段階大きい型という意味なのかな?
型の大きさは処理系 (アーキテクチャ) 依存だし、
ポータブルに書こうと思ったら思ったよりも面倒な感じ。
主要なアーキテクチャだけ対処できればいいなら
8 → 16 → 32 → 64
の拡張が出来ればいいので用意するパターンはそんなに多くはない。
ちなみに Windows の long double は double と同じ大きさだよ。 何種類か関数があるならtraitsを作成するのもありじゃない? 関数読んだら1段階デカい型が返ってくるなんて使う側でも面倒が起きそうだな まぁ、戻り値にも使用できるテンプレートの追加の型を関数内でconstexpr的に定義出来たらいろいろ面白いことが出来そうではあるなw 話は勝手に変わるけど、
{ 1,2,3,4,5 }
のような書き方が initializer_list になる場合とならない場合を全て知りたいけど
良く分からないので、誰か教えてくれまいか。 >>128
的を外しているかも知れないけど、その書き方をAと書くとすると、どんな文脈でも
A自体が最初に必ずいったん initializer_list<T> になった後にそれぞれの文脈で処理されるという
ことなのか、あるいは、
auto x {・・・};
auto x = {・・・};
auto x = TYPE {・・・};
func({・・・});
のようにいろいろな書き方や文脈が変わるとそもそも A は意味論的にすら
initializer_list<T> を経由せずにそれぞれ独自に解釈されて処理される
のか、どちらなんだろう???? あと、良く分からないのが、
struct CPerson {
・・・
CPerson(int a, int b, int c) {・・・} //(1)
};
とあった場合、
1. CPerson a{1,2,3};
2. CPerson a={1,2,3};
3. CPerson a=CPerson{1,2,3};
のどれを書いても多分、(1)が呼び出される気がするけど、
struct CPerson {
・・・
CPerson(initializer_list<int> a) {・・・} //(2)
};
と書いた場合、1,2,3 はやはり全て(2)が呼び出されるのだろうか? >>129
> initializer_list<T> を経由せずにそれぞれ独自に解釈されて処理される
initializer_list を経由しないことはある。
おおざっぱには initializer_list を受け取る文脈では initializer_list だし、
推論が必要なとき (auto やテンプレート) にも initializer_list に推論されるが、
そうでないときは initializer_list を経由しない。 >>130
優先順位がある。
1. 2. 3. のいずれも initializer_list としての解釈が「優先される」。
initializer_list を受け取るコンストラクタが存在しなければ
三引数のコンストラクタが呼出される。 >>132
なるほど。確認だけど、
1. CPerson a{1,2,3};
2. CPerson a={1,2,3};
3. CPerson a=CPerson{1,2,3};
4. CPerson a(1,2,3);
5. CPerson a=CPerson(1,2,3);
は、どれも3引数のコンストラクタで受け取ることは可能ということでOk?
1. 2. 3. は、initializer_list を受け取るコンストラクタでも受け取ることが可能?
4. 5. は、initializer_list を受け取るコンストラクタでも受け取ることは不可能?? >>133
(initializer_list を受け取るコンストラクタが無ければ) いずれも 3 引数のコンストラクタが起動されるが、
5. は 3 引数のコンストラクタでオブジェクトを構築した上で a にコピーする。
(コピーコンストラクタ、またはムーブコンストラクタが起動する。)
ただし RVO が有効な状況ではコピーやムーブはが省略されるので 5. は 4. と同じ。
そしてこの場合には関係ないが、波括弧によるコンストラクタ起動では引数の暗黙の型変換を許さない
といった重要な違いがある。
(initializer_list を受け取るコンストラクタが有る状況でも) 4. と 5. は initializer_list とは解釈されない。 >>134
1. 2. 3. は、initializer_list を受け取るコンストラクタでも受け取ることが可能?
4. 5. は、initializer_list を受け取るコンストラクタでも受け取ることは不可能??
については? >>135
それが区別できるだけのルールは既に提示したつもり。 >>136
すまん。もう一度明言してくれるとありがたい。 template <int N> void test(std::bitset<N>& arg);
int main()
{
std::bitset<1ull> lvalue;
test(lvalue);
}
これ、Nが推定できないのはなんで? すまん、自己解決
unsigned long long Nが正解だった >>135
> 1. 2. 3. は、initializer_list を受け取るコンストラクタでも受け取ることが可能?
はい。 可能です。
> 4. 5. は、initializer_list を受け取るコンストラクタでも受け取ることは不可能??
はい。 不可能です。
ところで >>134 で、オブジェクトを構築した上でコピーするのは 5. と述べたけど 3. もそうやな。 >>138-139
正解は size_t だよ。
size_t が具体的にどの整数型に対応するかは処理系定義なので
もちろん unsigned long long と等価なこともあるだろうけど。 >>136
念のため、その「述べた」はずのルールがどの文章だったのか教えてもらえれば
ありがたい。 vector<long long>を取る関数にvector<int>を渡すと、その引数はvector<long long>にキャストされる
で、vector<int>を取る関数にvector<long long>を渡すのはNG
この理解は合ってますでしょうか 間違ってる
vector<long long>とvector<int>には何の関係もない
intとstringに関係がないのと同じくらい関係ない pair<int, int> は pair<long long, long long>にキャストできるけど
vectorにそういうコンストラクタはないな >>103
VS6.0の頃は地獄だったよ
forループの変数は生キノコるわ例外出たら自動変数の破棄全部ぶっ飛ばすわでMSはクソの集大成だと確信していたわ 例外処理が2系統、数え方によっては3系統あるのがね STOUT を STDOUT に空目してこそプログラマ脳
「ミロ」そっくりの缶ビール 子どもが誤飲し販売禁止に(豪) - Yahoo! JAPAN
https://article.yahoo.co.jp/detail/1a7b2e0b9ab108ebf156f22e654f60634c39c88b
子どものみならず大人にも大人気のココア味の麦芽飲料「ミロ」は、世界中で愛されている。このほどオーストラリアの企業が、
ミロにそっくりのパッケージデザインで缶ビールを製造したことにより「子どもが間違えて飲んでしまった」という苦情が届いた。
これにより同製品の広告使用禁止が言い渡されたことを『news.com.au』などが伝えている。
問題の缶ビールは、豪ビクトリア州にある企業「Howler Brewing Company」の「Chocolate Milk Stout」というチョコレート風味の黒ビールだ。
缶のデザインは有名な麦芽飲料「ミロ」を真似たもので、お馴染みの緑色を背景に製品名や販売会社を示す文字の色やフォントまで同じデザインとなっている。
同社はこれまでにも、Instagramや炭酸飲料「スプライト」など認知度の高いロゴデザインを真似た製品を作り出している。 関数オブジェクトじゃなくて関数を記述するメリットってなんかある?
テンプレートは近々関数オブジェクトの方でも使えるようになるんでしょ? >>150
じゃあそのうち「関数はレガシーな書き方なので関数オブジェクトを使用するようにしましょう」とか言われるようになるの? >>149
複数の関数から呼ばれる関数どうすんのさ
グローバル変数や引数にいちいち入れるの? >>146
forの変数スコープは回避策あったやん
98年発売なんでもうちょっとどうにか出来たのではとも思うが あ、すまんラムダじゃなくて関数オブジェクトか
確かにタイプ数くらいしか思いつかんけど
テンプレートは既に使えるのでは?関数テンプレートに出来て関数オブジェクトに出来ないテンプレートの使い方あったっけ >>148
日本でも煙草を真似したデザインのチョコレート菓子があったけど
間違って煙草食った子供が死んだとか裁判になったとか聴かないな
おそらくあったんだろうな >>154
実体化の制御かね。
関数テンプレートは使用されない限りエラーにならない。
SFINAEもそうじゃなかったっけ? クラステンプレート内の普通のoperator ()だとそうだね
operator ()がテンプレートの場合ならほぼ関数テンプレートと同じ事出来るとは思うけど
文法上、明示的にテンプレート引数指定する際、関数と共通の書き方には出来ないな・・ Rustのメモリ安全性はボローチェッカーによって担保されているが、
Nimと比較してRustはタイプ量が多い事により限りなく低い生産性と
C++のような高い難読性、超巨大なバイナリ生成性能を兼ね備えています
Nimはバージョン1.5.1でRustのボローチェッカーに似た「View types」が実装されれば、
GC無しでView types参照の有効性を検証することによってメモリ安全性を保証しつつ
限りなく抑え込まれたタイプ量で高速化したCのソースコードを吐き出せます
Nimソースコード ==nimコンパイラ==> Cソースコード ==Cコンパイラ==> バイナリ
なので、nimコンパイラが通った時点でメモリ安全性が担保されませんか?
Nimの実験的特徴
著者: アンドレアス・ルンプ
バージョン: 1.5.1
http://nim-lang.github.io/Nim/manual_experimental.html
Nimは限りなく抑え込まれたタイプ量で高い生産性とPythonのような高い可読性を実現し
ているにもかかわらず、Cのソースコードを吐き出せるのでC言語でリモートワークされ
ている方は割り振られた仕事が早く終わっても終わってないふりをして怠けることができる
「怠け者とはこうあるべきだ!」と言うとても大事な事を Nim は我々に教えてくれます 質問です。
std::array ary = { 1, 2 };
↑の{}で初期化すると、
要素数を自動推論できるようにするにはどう実装すればいいんでしょう? >>155
食ったところで飲みこまずにペッペッて吐き出すだろ Rustのメモリ安全性はボローチェッカーによって担保されているが、
Nimと比較してRustはタイプ量が多い事により限りなく低い生産性と
C++のような高い難読性、超巨大なバイナリ生成性能を兼ね備えています
Nimはバージョン1.5.1でRustのボローチェッカーに似た「View types」が実装されれば、
GC無しのView typesで参照の有効性を検証することによってメモリ安全性を保証しつつ
限りなく抑え込まれたタイプ量で高速化したCのソースコードを吐き出せます
Nimソースコード ==nimコンパイラ==> Cソースコード ==Cコンパイラ==> バイナリ
なので、nimコンパイラが通った時点でメモリ安全性が担保されませんか?
Nimの実験的特徴 バージョン1.5.1
http://nim-lang.github.io/Nim/manual_experimental.html
第二プログラミング言語として Rust はオススメしません Nim をやるのです
https://wolfbash.hateblo.jp/entry/2017/07/30/193412
Nimは限りなく抑え込まれたタイプ量で高い生産性とPythonのような高い可読性を実現し
ているにもかかわらず、高速なCのソースコードを吐き出せるのでC言語でリモートワーク
されている方は割り振られた仕事が早く終わっても終わってないふりをして怠けることができる
「怠け者とはこうあるべきだ!」と言うとても大事な事を Nim は我々に教えてくれます std::chrono::time_point::time_since_epoch()が返すエポックタイムの原点はいつですか?
もし具体的に規定されていないとしても、
ミリ秒パートが0であることは保証されていますか? ある意味自己解決しますたorz
https://cpprefjp.github.io/reference/chrono/system_clock.html
>C++17 以前の場合、system_clock のエポックがどの時間を指しているかは未規定だが、ほとんどの処理系は UNIX 時間(1970年1月1日0時0分0秒)を指している
>C++20 以降の場合、system_clock のエポックは必ず UNIX 時間(1970年1月1日0時0分0秒)を指す
しかし(特にC++17以前において)ミリ秒パートが0が保証されているのかどうかがはっきりしませんぬ、 生年月日をUNIX時間で表現できないオッサンはこのスレにどのくらいいるの? 生年月日ならミリ秒まで言える必要は無いが
ログの時刻を極力正確に(WindowsのGetLocalTime()と同じ時刻で)記録したいのでつ∀`;) B.E.って何ですか
UCとSEとかRCとかじゃないの ていうかsystem_clockはC++17以前からtime_tと相互変換できるのに(system_clock::from_time_t()、system_clock::to_time_t())、
エポックがどの時間を指しているかは未規定とかおかしくね↑? 別におかしくない
変換時にエポックの差の分ずらせばいいだけだろ そんなことよりなんでtime_tは符号なしなん?
64bit拡張するときに符号ありにしとけば166みたいな煽りを受けずにすんだのに 符号付き整数はwrap aroundしたときの挙動が処理系依存か何かだったはず……
ハードウェア例外を生じるやつがあるらしい >>173
純粋にプログラミングスキルの話と受け取った>>167に謝れ >>175
オーバーフローしたときにラップアラウンドさせる使い方が数値計算としては特殊だからねぇ。 >>174
time_tを符号なしにしたやつはアフォだと思うが
それをもって符号なしを使うやつ全員が例外なくアフォというのは
早まった一般化という誤謬だ そういやーまだご存命の方もいらっしゃるんでしたね
>>179
符号付きにしたら2038年問題が2004年問題になってた
人類は間に合わなかった ヒトラー「2036年、人類と云われる者は居なくなっている」 関東大震災だって100年も猶予があっても何もしない國ですし 色々やってるぞ
庶民を助ける政策をやってないだけで https://twitter.com/cpp_akira/status/1430779310885859330
最近はC++の発表資料を公開すると「Rustでいいじゃん」というコメントがたくさんつくのか…。
Rustへの言及とか一文字も書いてないのに。
普及活動だと思うけど、さすがに嫌がらせチックに見える。
https://twitter.com/moriyoshit/status/1430795812552863744
C++の件に限らず、旧来からある言語の長所短所を理解せずに、
表面的に新言語を推す発言を見ると、
果たして当人は新しい言語の方も理解できているのだろうか、
という疑念をもってしまう...
https://twitter.com/5chan_nel (5ch newer account) >>186
Rustはいらんけど、制約を強化してコンパイルエラーを増やしたc++--は欲しいなぁ。
スライシングはすべてコンパイルエラー、ダウンキャストはメンバー関数とフレンド関数のみ使用可能
new deleteはメンバー関数とフレンド関数のみ使用可能(global operator new/deleteは廃止)
といったメモリ周りの制約強化は欲しい。 Rustを使って欲しいなら、そう言えばいいのに
人のすることを小馬鹿にするような態度で来るから敵と見られるんだよ
コミュ障にも程がある インテルコンパイラの-fastには-staticが含まれてるけど、なんでスタティックリンクは速いの? スタティックリンクにすると最適化の情報が増えるというのもあると思う。
C/C++ では翻訳単位ごとにコンパイルしてからリンクするという工程を踏むから、
コンパイル時には他の翻訳単位の情報を知らず、他の翻訳単位の情報を利用した
最適化が出来なかった。
今では LTO が当たり前になって、リンク時にあらためてコンパイラに戻して最適化
させる仕組みがあるんだけど、バイナリ自体が別物だとその仕組みを使えない。 std::threadってスタックサイズを指定できないってマジ?
仮想メモリを使えない組み込み用途だとどうすんじゃ…… native_handle()関数で環境に応じたスレッドハンドル(linuxならpthread)を取得できるから、スタックサイズを設定するところだけ環境ごとに用意して切り替えればいいよ Windowsみたいにスレッドハンドルを生成したときはスタックサイズ指定済のとき、みたいな
組み込み用OSがあったらどうすんじゃ…… とわいえμITRONのcre_tsk()は
>cre_tsk でスタック領域を明示しない場合のタスクのスタックや割込みハンドラ/割込みサー
>ビスルーチンのスタックは、OS が用意する「スタック用メモリ」から割り当てられます。
>スタック用メモリのサイズを定義する STKMSZ の標準値は 0 で、この場合、main 関数が使って
>いる処理系のデフォルトのスタック領域(スタックセクション)を、OS のスタック用メモリとし
>ます。この場合の実際のスタックサイズは、リンカでのセクション設定とスタートアップルー
>チンでの初期スタックポインタ値で決まります。
みたいなことが書いてある
C/C++界隈はみんな頭おかしい…… ゴメ勘違いcre_tsk()(IDがOSが自動割り当てのやつはacre_tsk())は
第2引数に与えるT_CTSK構造体でタスクごとにスタックサイズを指定できたわ;;;
なんでstd::threadではできないんじゃ…… コイツ前スレでも連レスしてたムーブ全く理解してないバカだよね?
NGしたいからトリップつけてください >>192
標準じゃ無理でしょ
全てのスレッドを変えたいならリンカのオプションとかで指摘できる環境もあるけど
boost::thread使って
boost::thread::thread_attribute::set_stack_size()
で設定するがよろし
>>193
native_handle()関数でハンドル取れると言う事はスレッド開始してる
開始済みスレッドのスタックサイズを変えられる環境って聞いたことない >>197
完璧な理解をサンプルコード付きで示したやろうが;;;
論点はなんでムーブに置き換えられるケース(明示的にstd::move()したら明らかに効率的なコードになる
において最適化でムーブにならないのか?なのだが高度すぎるのか文盲か故に>>197が付いてこれていないだけ
>>197はブーメラン もっとも天才の漏れは答えにたどりついたがな
ムーブコンの実装がコピコンの実装より効率的である保証が無い以上、
置き換え可能なケースであってもコピコンからムーブコンへの機械的置き換えは正当化されない Rustみたいにコンパイル時にいちいち参照のチェックするんじゃなくて
C++で最終的に完成したバイナリに対してメモリサニタイザーを一回動かす
ってのではだめな理由ある? >>203 動かしたフロー以外のフローについて不安が残るし、サニタイザーの精度がどれほどかという問題もありそう。 >>203
ものによって賢さの程度が違うから一概には言えないけど
基本的にはサニタイザは実際に起こった問題を検出するものなので
入力値次第で問題が有ったりなかったりするようなケースを検出できなかったり、
言語仕様上で未定義なものがたまたま問題ないアクセスになってしまうようなケースも
検出できないかもしれない。
問題が起こっていて再現条件が分かっているときに検証するツール、つまりデバッグ用のツール
としてはサニタイザは有用だし、ごく基本的なテストツールとしても使えるけど、
Rust のライフタイムチェックほど網羅的ではない。 MozillaのFireFoxの場合、わざとクラッカーがセキュリティーホールを見つけ出して
そこを付いてくるから、普段の実行テストでは一度も発見できなかった
メモリーバグが問題になるが、普通のアプリの場合、ユーザーがわざとバグを
付くことはないから、そのようなホールはあまり関係ないと思う。
テスト駆動開発とかアジャイル開発とかも、普段使いで問題が無いかをテスト
することで大部分のバグが無い状態で開発していこうとする考え方。
それでもほとんどのメモリーバグは無い状態になっている。
メモリーバグがあると、普段使い的なテストをしても発覚することが多いから。
昔から言われているメモリーバグの問題点は、再現性が有る場合でも、バグが
ある行とそれが発覚した時期とがずれていることがあるから。
デバッグモードでコンパイラが自動的にチェックするコードを入れていれば、
それはなくなるはず。
Rustはその意味で、経験法則的にFireFoxみたいな特殊なものでは意味があるが
一般アプリでは余り意味が無い。ブラウザの特殊性は、世界中のクラッカーが
セキュリティーホールを探してわざとその穴を付いてくること。一般アプリでは
それがないので、隠れたバグは隠れたままになっていることが多くて、
テストで出てこなかったバグは実際問題的には余り問題となら無い事が多い。 >>207
例えば、ダングリングポインタ(Use After Free)は、ptrがどこかでまだ使用中なのに、
free(ptr)としてしまうこと。しかし、そのfree()をした時点ではアプリはダウン
しないし、ptrに対して読み書きした段階でもまだ発覚せず、ptrが指すメモリー
アドレスを別の目的で使用してしまって、お互いに読み書きがある種の干渉を
起こしてしまって、データがめちゃくちゃになり、それによってどこかで不具合
が生じた時点で発覚する。
なので、バグの根本原因であるfree(ptr)を実行した行がどこかを探し出しにくいと
される。
しかし、このバグの場所とバグが起きた場所のずれは、デバッグビルド時に速度を
落としてチェックすれば本当は防げるはず。 >>208
チェックと言っても人間が手で書く必要は無く、コンパイラがチェックコードを
自動生成できるはず。 >>207
世の中にはテスターという職種の人がいてだな >>207
任意のファイルを読むアプリはファイルのパーサーの脆弱性をついてユーザ権限でコードを実行される可能性がある
どちらかと言えばアプリよりサーバとしてアクセスを受け付けているプログラムの脆弱性をつかれて攻撃コードの実行を許してしまうことが多い
さらに上のような場合でも、アプリやサーバのプログラム自体に脆弱性があるのではなく、使用しているOSのAPI側の実装の脆弱性をつかれる可能性がある
こういうアプリやサーバやOSのコードの脆弱性にMSやGoogleは悩まされている Valgrind と言う動的解析ツールを調べて見るといい
うちはC++のプログラムは基本これを通すことになってる
商用ならもっといいツールもあるかも知れない
そういうのを利用しても充分でないから静的解析するRustが注目されている 商用の静的解析ツール使ってると、正直メモリ関係のバグなんてありえないと思えるくらいいろいろ見つけてくれるよ コンパイル時間に糸目を付けなければ、静的解析はもっと出来る。 > メモリ関係のバグなんてありえないと思える
lintの副作用がモロに出てるなw 言うまでもない事だが完璧なメモリチェッカーは存在し得ない
停止問題と同値だからな 完璧無理っておまえの毛髪の量がプログラム停止に与える影響が読めないとかそういう話だろ?
限定的な範囲で正しけりゃ十分だよ OSのコアダンプ出力とリブートに救われる手のひらの孫悟空 rustでもメモリアロケーション失敗するとパニックになる、てリーナスが突っ込んでいたろ。
c++の場合はどうなんのかな。 CoverityとVectorCASTは使ったことあるけど検知レベル最高にしても見逃すリークや二重フリー, ダングリングはそれなりにある (そもそもコードの構造が悪い場合も多いが)
検知レベル上げ過ぎると逆にFalse Positiveも増えるし ∞の概念が理解できるならそいつはもう文系ではあるまい 超久しぶりにC++の参考書 買った。
いまってC++20までいってるんでしょ?
時代遅れもいいところだから勉強しようと思ってw
ただ読む気がおきない。
「pythonでいいか」って思いが・・・ww >>223
https://tabesugi.net/memo/2009/1a.html
C++ はひどい言語だ。これは、多くの平均以下のプログラマーが使ってるために
さらに輪をかけてゲロゲロになっていて、どうしようもないゴミが
簡単に生産されるようになってる。正直いって、C を選ぶ理由が C++ プログラマーを
追っぱらうため *だけ* だったとしても、それ自体、C を使う強力な理由になりうる。
C++ はトンでもなく悪い設計の元になりうる。どうせこの言語ではいつも STL やら
Boost やら、その他ゲロゲロベロベロの「素敵な」ライブラリの機能を使って、
それがあんたのプログラムに「役立つ」んだろうが、以下のことが起きる:
- うまく動かないときにもたらされる際限のない苦痛 (あと STL とか、特に Boost が
安定してるとか移植性があるとかいう奴は、どいつもこいつも大ウソつきで、
もはや笑えるレベルを超えている)
- 非効率な抽象プログラミングモデルで、2年たった後にこれらが実はそんなに
効率的じゃなかったことに気づくケース。でもそのときにはすでに全部の
コードがその素晴らしいオブジェクトモデルに依存していて、直すためには
アプリ全体を書き直さなきゃなんない。
言いかえれば、唯一まともで、効率がよくて、システムレベルで使えて、移植性がある
C++ ってのは、基本的に C で使える機能だけに限ったときなんだ。そして C だけに
限定するってことは、他の人がそれをめちゃくちゃにしないってことで、
ついでに沢山のプログラマが実際に低水準の問題を理解することができて、アホらしい
「オブジェクト・モデル」のたわごとを持ちこまないってことだ。 linusに言われると返す言葉もないが、その後の文脈にある
『もし C++ で書かれた VCS が欲しいのなら、Monotone を見てみるといい。
ほんとに。連中は「本物のデータベース」を使っているよ。
「素敵なオブジェクト指向ライブラリ」も使ってる。「ナイスな C++ の抽象化」も
使ってる。そして率直なことろ、一部の情報系の人間が喜びそうな
これらすべての設計上の決定のために、できてきた結果はゲロゲロで
保守不可能なカオスだ。
でもあんたはきっと git よりも気に入るだろう。保証するよ。』
な感じでC++を気に入って、夢を見ていたいんだろうね。 「オレはC++を使いこなせている」と思い込む素人を生温かく見守るスレはここですね 昔、バカでも使える言語でプログラマ人口増やしましょうてなことやってたな
BASICじゃないぞ、あれは初心者用で、バカ用じゃない
計算を数式で書くのは理系だけだから
英文で書けるようにして文系でも使えるようにしようという試みがあった
で、狙いどおり本当にバカプログラマを量産できた
それでいいことあったか?
C++はアレの逆をいっているわけだ >>234
Linuxはモノリシックカーネルなので動的メモリ確保を伴うような軟弱な
モジュールもカーネルのうちに入ってしまっているからメモリ不足ぐらいで
パニくられると手の打ちようがないから困るという話なんじゃないの(適当
OSはリソース管理を放り投げて停止することは許されないから
伝統的なやり方では起動時に非常用のメモリブロックをアロケートしておいて
メモリが枯渇したら非常用のメモリブロックを使うみたいな手段がとられる(と思う
がパニックされたらそこまで行きつかない
※ 個人の感想です >>239
具体的に何かのケースを想定して言ってるわけじゃないのか。
ぶっちゃけOSをC++で書くならカーネルでnew/malloc/mmapとか使う実装はしないだろうし、処理系が使うランタイムにも依存するけど基本その辺はカスタマイズできるようになってると思う。
rustでもそんな感じで処理系次第って話だと思う。 >>241
>>230 の類の話は昔からいわれていたもので、これも有名ですね
http://www.kh.rim.or.jp/~nagamura/misc/stroustrup-interview.html
インタビューア(以下「I」): あなたがソフトウェアデザインの世界を一変させてから何年にもなる。振り返ってみて、感想は。
Stroustrup(以下「S」): 実はあなたがここへ来る直前、当時のことを思い出していたんだ。おぼえているかな。誰もが C 言語を使っていたけど、問題はみんな結構うまくコーディングしていたことだった。
大学も C 言語を教えるのがうまくなっていたしね。驚異的な割合で有能な――「有能」という言葉は強調しておきたい――卒業生を量産していた。それが問題の原因だったんだ
。
S: ある日、オフィスにいたときに、ある策略を思いついたんだ。バランスを少し回復させる策略をね。「プログラマが余るなんてことが絶対にありえないくらい、複雑でおぼえにくい言語があったらどうなるかな」ってね。
実は、この考えの一部は X10――例の X Window の――から頂いたんだ。あれはひどいグラフィックシステムでね、Sun 3/60とかでないと動かなかった。
ばかばかしいくらい複雑な構文規則とか、わかりにくい関数とか、疑似オブジェクト指向的な構造とか、僕がほしいと思う要素は全部揃っていたんだよね。
今でさえ、生の X Window コードを書く人間なんていない。正気を保つには Motif を使うしかないんだ。
S: もうかなり時間がたったしね、C++ が時間の無駄だということにはほとんどの人が気がついたとは思うけど、でも当初予想していたよりはずいぶん時間がかかったな。
I: 具体的に何をどうやったのかな。
S: 最初はほんの冗談のつもりでね、みんながあの本を真に受けるとは思ってもみなかったんだ。脳みそが半分でもあれば、オブジェクト指向プログラミングが非直感的で、非論理的で、非効率なことくらいはわかるよね。
I: え?
S: それに「コードの再利用性」ときたら…。どこかの会社がコードを再利用したなんて話を聞いたことがある?
I: うん、でも C++ は基本的にはしっかりした言語だと思う。
S: それ、本気で信じてるね。実際の C++ プロジェクトの経験はある? どうなるかって言うとね、まず第一に、いろいろワナを仕掛けてあるから、よほど小規模なプロジェクト以外は一発では動かないようになっているんだ。
たとえば演算子のオーバーロードがそうだ。たいていの場合、プロジェクトの終わり頃にはほとんどのモジュールで演算子をオーバーロードしている。
プログラマの連中が、トレーニングコースで教わったとおりにやらなくちゃいけないと思うからだ。つまり、1つの演算子の持つ意味が、モジュールによってまったく異なることになる。
モジュールの数が100かそこらあるときに、これをまとめあげようとしたらどうなると思う? データ隠蔽もあるね。モジュール間の連繋にどこかの会社が苦労しているなんて話を聞くと、笑いを抑えられないときがあるよ。
「Synergistic」という言葉は、プロジェクト管理者の胸に刺さったナイフをグリグリ回すためだけに発明されたんじゃないかと思うな。 https://ideone.com/fHH1N4
これが、シングルトンとして抜けている理由を教えて下し亜。
コードのストックにするために書いたのですが、そもそもシングルトンってなんでしたっけ? >>243
誰が書いたかなどどうでもよく、その内容についてはどう思いますか? >>244
関数テンプレートが結果的に引数の数が違う関数として展開される。
引数の数の違いが結果の違い。 >static std::shared_ptr<T> O = std::make_shared<T>(A...);
の部分って、Singleton()の初回呼び出しが複数のスレッドから同時に起こってもき
ちんと排他してくれるんでした
っけ
また排他してくれるとしても最速(そのアーキテクチャ(マルチコアかもしれない)で最も適切)
であることを気体していいんでしたっけ……
つまり生成に成功した後は排他不要なわけで、無駄にロックを取りに行きたくない…… みたいな配慮がシングルトンにしたとたんに必要になる
メインの処理が始まる前に普通の初期化関数呼び出しでOを生成したらそれで済むのに、、、 >>247
呼ばれたところで最後の奴が勝てば問題ないのでは >>250
ある
>static std::shared_ptr<T> O = std::make_shared<T>(A...);
全体が排他されないとしたら、Oの生成関数(初期化式「O=」の右辺)が複数回、
それも同期的に繰り返し呼ばれるのではなく、非同期的に再入される形で呼ばれかねない
生成関数の中でリソース確保するとしたら先の呼び出しで確保したリソースの
ハンドルがdunglingにならないように配慮が必要になる
非同期的再入ということは、Oが生成→破棄→生成→破棄、にならず、
生成→生成→破棄→破棄になりかねないから、デストラクタをちゃんと書いたらリークしないとか
そういう認識で当たったらバグる
問題山積や
メインの処理が始まる前に普通の初期化関数呼び出しでOを生成したらそれで済むのに、、、 >>245
お前の質問なんかどうでもいいからデマを貼るな >>246を踏まえるとこんな感じか
関数テンプレートだけで済ます方法はあるのかな?
https://ideone.com/kmIimz >>248
はい、頭も性格も悪いと思います、しかし >>242 の中のどういうところが悪いとお考えになったのか教えていただくと嬉しいです!! >>255
そもそも、C++の生みの親で、それに関する書籍を出してその中でC++を
良い言語と自負して(それ以上の言語が出来ないというような主張も幾度もして)
解説し、まだ推進しようとしている人が、C++を徹底的に卑下するかどうかを
疑問に思ってないことも頭が悪いと思われる原因の一つ。 実際、C++は、特に初期の頃はCより全面的に優れていると誰でも思えるような
物であって、ちゃんと世界的に認められて広まっていたのに、その部分まで
全否定するようなことをインタビューで答えるわけがない。
その後に追加されて機能は人により評価が分かれて全面的に優れているとは
思えるようなものではなくなっていた。
だから、C++11は、好きな人も居れば嫌いな人も居る。C++98より全面的に
優れていると言えるかどうかは人により評価が分かれるので、好みにより
文壇の様なものが生じている。 >>254
ひ、日本語でおk、、、
>If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.85
>If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.
はどう読めばいいの?
結局concurrentlyにre-enterされるときはbehavior is undefinedとしか読めなさげ
>>254
以上の状況なので>>244の糞コードは直しても仕方が無い メモリを自動解放するfinally機能さえあればCでも大丈夫とは思う とオモタがcontrol enters the declaration concurrently のときは初期化のcompletionまでshall waitで、
ただしrecursivelyだとイカン(未定義動作)と書いてあるのか……
つまりSingleton()関数内の初期化式「O=」の右辺がSingleton()を呼び出す場合か
まあ確かにWindousみたいに特殊な仕様のクリティカルセクションでもない限りデッドロックしそう >>251
そうか
まあ仕様的にはスレッドセーフだわ
関係ないけど参照したグローバル変数に値が入っとらんで困ったことがあった >>258
なんかスレッド安全性の問題にしたいようだけど、
そもそも>>244の第一の問題点は2番目のSingletonの呼び出しだけ別のオブジェクトを指してしまっている点だよ
stdoutの2行目だけ0になってるだろ?
その原因の説明が>>246というわけだ
すべての関数・クラスを最初からスレッドセーフな設計にしないといけないわけじゃない ビャーネ・ストロヴストルップその人のインタビューだとは私も考えてませんよ、これはブラックジョークというべきでしょう、まあC++er が気を悪くする理由は理解できますが
それに私も GNU Multi-Precision Library を使うときはC++のラッパの方を使います。C インターフェースの方は使い難くって使い難くって、これはもう罰ゲームですね‥‥
だから演算子のオーバーロードも控えめに使えば有用という立場です、紹介することと賛成することとは別だと思います
https://mevius.5ch.net/test/read.cgi/tech/1434079972/84 >>263
スレッドセーフでなくともよいシングルトンとか
>メインの処理が始まる前に普通の初期化関数呼び出しでOを生成したらそれで済むのに、、、
で良くね?
>>264
>>263じゃないが非アトミックな操作(初回か否かチェックして初回なら初期化する)
であることが明示される分その書き方の方がマシ
必要なら排他する、不要ならしないという判断ができるから
>すべての関数・クラスを最初からスレッドセーフな設計にしないといけないわけじゃない (>>263)
という願いも叶うYO! >>264
確かに普通こんな感じだな
テンプレート別々にすることだけで頭止まってた
>>267
そうだな
書いてはみたがC++でシングルトン使う意味は無いと思う
あれはグローバル変数の無いJavaでグローバル変数を使うためのハックだとか聞いたし
じゃあもう普通にグローバル変数使えばよくね、と グローバル変数と同じなのでだめだよな
普通に動的に用意して渡せばよろしい ログとかアプリの現行設定ファイルとかはSingletonっぽく実装するけどなぁ・・・
インスタンス生成が遅いものはただのグローバルにしたら起動が遅くなるし >>268
最初のデザパタ本であるGOF本はc++とsmalltalkで書かれてるんで、javaは関係ないよ シングルトンはスレッドセーフが実現できれば問題ないでしょ >>255 >>265
これは「権威に訴える論証」を悪用した主張であり、議論の対象としてはいけない類のもの。
もし真面目に議論したいのなら、少なくともStroustrupの名前は消して内容だけに修正しなくてはならない。
本人も否定しているのに訂正もしないようなフェイク記事は邪悪。それに対してコメントを求めるのは正気を疑う。 その昔、こんなクラス作ってたな
class WinMainArguments
{
public:
static HINSTANCE hInstance;
static HINSTANCE hPrevious;
static LPSTR lpszCmdLine;
static int nCmdShow;
}; >>265
ブラックジョークは大半の人が聴いた瞬間にジョークだと判るから成立する
麦藁禿のあの名文はまさにそれ
だまされてるのは事情を知らない若い人かも知れんな >>277
初期のc++には名前空間が無くてなぁ。
標準化する前だから良く知らんが。 その初期のC++ってもしかしてEC++とかいうパチモンじゃないですかね 今更バイエルの運指について議論してるような雑魚に構うなよ
C++もピアノも、憧れだけあって実力がまるでないバカ 日本語版(0xCC=フ)によりフフフフフ…で埋められたWin32アプリデバッグメモリを思い出した人、どのくらいいるかな
「フフフ…」4歳娘が撮影した花火に家族で爆笑! 見ると笑顔になる“奇跡の1枚”の状況を父親に聞いた | FNNプライムオンライン
https://www.fnn.jp/articles/-/224754 >>278-279
D&E によればネームスペースは 1991 年に ANSI/ISO の委員会において浮上したトピックであるとのことだ。
逆に言えばそれ以前には無かった。
Windows 3.1 の頃に C++ でプログラミングしていたなら >>274 のようなコードが有ったとしても不自然とは言い切れない。 なあに名前空間的な修飾を省略させたくない時に役立つ >>259
cに付け加えるならgoのdefer文かなと思う。 C...Cにだってtry~catch~finallyあるんだからね!(ネタ=setjmp/longjmpを使ったマクロ)
https://gist.github.com/rampion/91594 >>286
ちなみにtry~catch~finallyっぽいのはVC++が持つと光と闇が両方そなわり最強に見える
Cが持つと逆に最適化が合わさり頭がおかしくなって死ぬ >>287
別に頭がおかしくなって死なないでしょ
finally機構で資源解放する機会が増えるのはユーザーの利益になるだけで、複雑さを増す不利益にはならないよ 確かにgccだと-O1でも2でも3でも暴走しちゃうけど、vc++だと最適化してもちゃんと動くね VC++はマイクロソフト拡張によってCでも構造化例外処理が使えたんだよね
__try __except __finally intalコンパイラはほんとにヤバいが、gccの最適化で変なことになったことは自分は一回もない finallyは20年前からBorlandC++に既に実装済だったしその頃のVC++なんか>>146の状態やし >>286
最近まで try.. catch の実装の大半は sjlj だと思っていましたが最近は違うのですか? >>273
あなたはジョークの分からない人か、それとも >>275 のいう若い人か
>>242 は >>230 と同様でしょ >>294
IDが出る板でID消してると浪人焼かれるぞ >>296
それは単なる都市伝説
お布施を毎年律儀に払っている人にそんなことをするわけがないでしょう‥‥ >>289の件、再現コード抽出しました。最適時i=1がlongjmp後に0に戻ります。
// gccだと最適化なしなら正常終了。最適化すると終わらない。
#include <stdio.h>
#include <setjmp.h>
int main(int argc, char *argv[])
{
int i = 0;
jmp_buf jmpbuf;
_setjmp(jmpbuf);
printf("hoge\n");
if (i < 1)
{
i = 1;
longjmp(jmpbuf, 1);
}
return 0;
} gccで例外ぽい事したいならC++にして使えで完結しちゃうからな…… インラインアセンブラとかでもない限り、処理系依存の文法を使いたくはないし、>>286はあくまでネタですよ。
ただ最適化時の挙動が違う原因を知りたかったので、個人的に調べた結果を載せといただけです。
お気になさらず。 setjmpの結果を変数に入れちゃダメだって教わらなかった? >>297
規制議論板を一度でも見たことがあるの?
どれだけのIDを消して書き込んでる奴が浪人焼かれてるかその目で確かめてくるといい コテとトリ付けながらIDは消すとかいうガイジムーブ
他スレでの荒らしがバレたら困りますって宣言してるようなもんだな笑 >>305
何を言いたいのか分からない無言URL貼りは時間の無駄なのでやめて欲しいです。少なくとも該当していません。 一応書いておくと、>>298のコードは見れば分かるとおりiをvolatile宣言して最適化の対象から外せば当然動きます。
これはlongjmpに限った話ではありません。
先のURLの個別のコードにはありませんが、一般論としての記述はありました。このサイトが元にしてるサイト(リンクのURLは違いましたが)ではvolatileも例に含まれているようです。
https://wiki.sei.cmu.edu/confluence/display/c/MSC22-C.+Use+the+setjmp%28%29%2C+longjmp%28%29+facility+securely すみません。見落としてただけみたいですね。日本語の方でも個別のコードありましたね。寝ぼけてたかも。 >>295
嘘記事かどうかくらいは書いておくべきだと思うがね
だいぶ前に初めて見たとき俺も半信半疑だったし(D&Eをまだ読んでなかった頃だが
てかオブジェクト指向のとこをテンプレート(メタプログラミング)に置き換えるとすごいしっくり来るんだよなアレ >>295
全然違う。
>>230は少なくとも本人の発言からの引用であり、(権威に訴える論証が混ざっているとはいえ)すべてを否定することはできない。
>>242は自分の主張を強化するためにでっち上げた嘘であり、本人の普段の主張を否定する邪悪な紛い物。本人も否定しているものをジョークと称するのはやはり正気を疑う。 >>295
一言言い忘れた。
ジョークを「主張」するなよ。アホか。 ダニングクルーガー効果のなんちゃってマスター状態でも容易に書けちゃうのが問題。
そのクソコードの状態でも一応動くところがC++の恐ろしいところでもあり幅広いフリーフォーマットの適応力でもある。 >>312
自粛警察乙
マスゴミに煽られるまま踊るのジュリアナのお立ち台みたいな気分? お前らってホント人にケチつけるときだけイキイキとしてんな オブジェクト指向も構造化も原理主義者がウザいだけで
ナンチャッテでいいからやってると問題がきれいに整理できるので
やめようとは全然思わない
テンプレートだってそうだ テンプレートってただの超絶便利機能だろ
オブジェクト指向笑とは比べ物にならない >>318
歴史は繰り返す、ってことだろ
一時期C++コミュニティがJavaに悪影響受けたりしてたことからJavaを嫌悪してたやつが
何でもSTLの真似してりゃ自動的に価値のあるコードになると盲信してたからな
笑うしかない 俺ら技術屋の辛いとこだよ
新しいものはとりあえず食ってみるしかない
あげくゲロマズで非常に気分が悪くなることもあるが怖がってらんない 技術屋というか、実用してる人は盲信はしないと思う
原理主義に走るのは、自分の頭で考えない(権威に頼る)からだ
自分の頭で考えて使ってれば、自ずと長所も短所もわかるもんだ >>311
人を選ぶジョークとはまさに >>242 のことだったんですね‥‥
今回は勉強させていただきました 分かったら二度とデマ流すなよ
ワクチンにマイクロチップだのどこそこの銀行が潰れるだの朝鮮人が井戸に毒入れただのもだぞ
本人は軽いジョークのつもりでも、デマとして流行したら人が死ぬんだからな > 原理主義に走るのは、自分の頭で考えない(権威に頼る)からだ
ほんこれ そうはいってもC言語規格にfinally機構があったら便利なはず
PGが規格追加に後ろ向きになってしまうのはコンパイラの対応が信頼できるレベルになるまで時間がかかる不快な経験を積んできたから デストラクタもないC言語にfinallyだけあってもねぇ… >>329
デストラクタがないからこそfinallyで資源解放処理を呼び出す需要があるともいえるんだけど >>331
実際に書いてみたらわかると思うけどどこからfinallyに来るのかわからないから解放処理書くのはけっこう大変だぞ ハノンフルボッコされて火病を起こしててワロス
自分が悪いのに逆ギレするほどみっともないことはないなあw 整形後に関数が10行以上になったらコンパイルエラーにしよう
関数名1行+開きカッコ1行+return1行+閉じカッコ1行だから実質5行までな たまにちびっこだらけのピアノ教室に一人だけ下手くそなおじさんが混ざってて臆面もなく発表会とかにも出てくるけど、それがその固定ハンドル 質問でsが
std::this_thread名前空間内の関数は、std::thread以外の手段で作ったスレッドで
実行しても大丈夫なんでしょうか、
一部のC標準ライブラリ関数みたいにスレッド起動手段次第でリークしたりすることは無い?
https://cpplover.blogspot.com/2010/10/msvc.html >>341
やってみないと分からないから自己責任でご自由にどうぞ、というのが正しい回答 >>342
std::thread以外の手段で作ったスレッドで実行したときのふるまいは
規格上非規程ということでおk? 未定義動作とか処理系依存とかではなく、規定されていないということ? 大丈夫なんじゃないすかね
mainはstd::thread以外の手段で呼び出されるんだし >>326
米国民主党の宣伝=ロイター・ブルームバーグ=真実
米国共和党、なかんずくプレジデント・トランプの言ったこと=フェイクニュース
という理解でいいでしょうか?イヴェルメクチンの話 https://www.youtube.com/watch?v=zhIg_KNfyhQ
>>338
どこがフルボッコか詳しく、ジョークのわからない馬鹿一人だけが騒いでいた、という印象ですが
>>340
バッハコンクール大人の部には出てみたいですね‥‥たぶんよくできる中高生のなかに一人ヨボヨボが混ざるの図になりそうですけれどもね >>347
コンクールとは無縁の音楽歴だろうがクソバカが
見栄張んなよ
精々弱小音楽教室の発表会止まり わかるよ
C++とはつまりCから2キー(2半音)上げたDという意味
ピアノならCはドでDはレ このスレにMIDIエンジンを自分で作ったことある人、どのくらいいる? ピアノじゃなくても「CはドでDはレ」だと思うが…… MDLを入力してWAVを出力するコンパイラみたいのなら >>351
思うだけならあなたの自由だから好きにしなさい >>351
世の中には移調楽器って言うものがあって、例えば普通によく見かけるトランペットはドの音はB♭だったりする Windowsの標準システムドライブがCであることの経緯を知らないでPGやってる人、どのくらいいる? >>350
SWFreaderのこと?
SoftwareSynthesizerのこと? MIDIなんてPC-98以前のFM音源搭載機でしかいじらなかった
MIDIドライバとかならともかくMIDIエンジンが何なのかよく分からない >>348
スレチガイも大概だからここで終わりましょうか
バッハコンクール https://www.bach-concours.org/p/about.html
趣旨「J.Sバッハの作品はクラシック音楽の真髄、導入期からポリフォニー音楽や舞曲に親しみ、ピアノの学習の中に取り入れて、そしてレパートリーにしていただきたい」、おっしゃるとおり誰でも参加可能です
https://matsuri.5ch.net/test/read.cgi/piano/1488364000/
バッハはこんな曲を作った人:https://www.youtube.com/watch?v=SBWGgwzcjYc
確かアニメ監督の押井守は若い頃バッハの合唱団にいたと聞いています 関数のポインタを引数で受け取る関数に
予め定義した関数のポインタの代わりに
lambda関数のポインタを渡したいとき
どう書けばよいですか? >>363
ラムダ式を呼び出すラッパー関数を作って、その関数ポインタを渡す >>363
こういうこと?
void func1(void (*arg)())
{
arg();
}
template <std::invocable F>
void func2(F arg)
{
arg();
}
int main()
{
func1([]{});
func2([]{});
} >>363
違うかも知れんけど、関数ポインタとラムダと型推論でなんかハマってこの記述に落ち着いた。
ttps://ideone.com/UNUgdi >>363
クロージャ (ラムダ式によって作られた関数オブジェクト) は周囲の変数をキャプチャしないときに限り関数ポインタに変換可能。
https://timsong-cpp.github.io/cppwp/n3337/expr#prim.lambda-6
逆に言えばそうでないときは関数ポインタと互換性はない。
受け取る側が関数ポインタとして受け取るという前提を動かせないのであれば
渡すラムダ式のほうをキャプチャしない形にしてくださいということになるし、
汎用的にラムダ式を受け取れるようにしたいのだということであれば >>365-366 という方法をとることになる。 >>366
template<typename F> void func2(F arg) { arg(); }
int main() { func2([]{}); }
↑
これだと動いています
void func1(void (*arg)()) { arg(); }
int main() { func1([]{}); }
↑
やりたいのはこっちだったんですがこれはコンパイルエラーになりますた
# invocable は C++20 からみたいですね 目的にあってるかどうか判りませんが試す環境が今無いので後回しです >>368
ああなるほど
[&] してたのが原因かも知れません
ありがとうございます 聞いてくれウィンドーズ10で
GetLocalTime(&st1);
const system_clock::time_point now = system_clock::now();
GetLocalTime&(st2);
とした後に、nowから
const time_t tt = system_clock::to_time_t(tp);
auto msec = duration_cast<milliseconds>(tp.time_since_epoch()).count() % 1000;
としてnowのms単位のUNIX Timeを算出したらば、
st1 ≦ now
は当然成立しているが、
now ≦ st2
は成立しないことがあり、何か
now ≦ st2 + 1
なんじゃわ;;;
何で?! 処理系はMSVC2019でつ、
duration_cast<T>はTで指定した時間単位未満は切り捨てとC++の規格で決まっているはず…… ちなみにst1 < st2 でありかつ (now ≦ st2) が非成立、というケースも発生するあるから
おかしいのは明らかにstd::chronoの方、 >>377
これだけじゃどっちがおかしいかは分からんでしょ
GetLocalTimeが正しいと思うからGetLocalTimeでsystem_clock::nowを挟んだんじゃないかい >>378
>>377のは時刻のキャッシングみたいなことをしており呼び出した瞬間の時刻を返していないとしたらそれはGetLocalTime()の方ではない、という証左
つなみにマルチコアと最適化(いやしくもAPIの呼び出しがあるのであり得ないが)とプリエンプションの合わせ技で
実行順序が変になり得るかも、みたいな被害車妄想で
GetLocalTime(&st1);
const system_clock::time_point now = system_clock::now();
_ReadWriteBarrier();
GetLocalTime&(st2);
としてみたが>>377な現象は変わらんかったは、 windowsのAPI同士で比較しろ
一般に違うAPIを使ってるなら一貫した結果にならなくてもおかしくない ちゃんと知りたいならsystem_clock::nowが内部でどのAPIを呼んでいるのか調べてみては unsignedとintを比較してるとかどうせそういうオチだろ 中途半端なコードだけチラ見せされてもな
再現する完全なコードを出せとしか >>386
天才なのでそんなヘマはしますしません、
>>387
再現コード貼る、
https://ideone.com/GeMebI
※ 冒頭コメントの通り、非Windows環境では現象再現しないコードなのので注意
ウィンドーズでの実行結果:
i=---: st1, chrono, st2: ORDER CHECK
i= 0: 1632034143228, 1632034143228, 1632034143228: OK.
i= 1: 1632034143229, 1632034143229, 1632034143229: OK.
i= 2: 1632034143229, 1632034143229, 1632034143229: OK.
i= 3: 1632034143229, 1632034143230, 1632034143229: NG!
i= 4: 1632034143229, 1632034143230, 1632034143229: NG!
i= 5: 1632034143230, 1632034143230, 1632034143230: OK.
i= 6: 1632034143230, 1632034143230, 1632034143230: OK.
i= 7: 1632034143230, 1632034143231, 1632034143230: NG!
i= 8: 1632034143230, 1632034143231, 1632034143230: NG!
i= 9: 1632034143230, 1632034143231, 1632034143230: NG!
==> ORDER CHECK 「NG!」のところでchrono > st2 になっており、chronoのtime_pointがSYSTEMTIMEを1 msだけ追い越している こっそり訂正するが、>>377で
>st1 < st2 でありかつ (now ≦ st2) が非成立、というケースも発生するあるから
と言ったがな、ありゃ誤報だスマンカッタ、
あとちなみに、>>375を書いた時点では、現象再現はFILETIMEを使わずに、以下の方法で、
SYSTEMTIMEと ( (time_point - epochタイム) を tm構造体に変換したもの、の
それぞれからから直接シリアル日時を出して比較すた、
year * (12 * 31 * 24 * 60 * 60 * 1000)
+ month * (31 * 24 * 60 * 60 * 1000) // 一ヵ月の日数を31固定で換算しているが、大小比較目的なのでこれで問題無い。
+ day * (24 * 60 * 60 * 1000)
+ hour * (60 * 60 * 1000)
+ minute * (60 * 1000)
+ second * (1000)
+ millisecond まともに読んでないがバリアの使い方がおかしくて実行順序入れ替わってるとかじゃね?? >>390
(1) _ReadWriteBarrier()は最強のバリアーやぞ;;;
(2) GetLocalTime()がどんな副作用を持つ関数かコンパイラが知るはずは無いのだから
最適化でコードの入れ替えや変数のレジスタ割り当てしっぱなしということはあり得ない
(3) ていうかそれ以前に、GetLocalTime()やstd::chronoの呼び出し元がシングルスレッドなのだから
それで順序がおかしくなるとかCPUがおかしいか、スレッドをプリエンプトして再びディスパッチする際に
別のコアに実行させようとする際にOSがヘマしているかのどちらかという話に……
ちなみに漏れは正常動作しており、本人が言うのだから間違いない https://gist.github.com/t-mat/3763854
Windows10ならSYSTEMTIMEよりsystem_clockのほうが精度高そうですね >>375
GetLocalTime の分解能は 10ms くらいっぽいぞ。
system_clock::now がもっと精度の高い API を使っていたら
そんくらいの前後はあってもおかしくないんじゃね。 https://ideone.com/qA5yOL
system_clockの部分を生のFILETIMEで置き換えてみた
実行結果はこんな感じ
i= 0: 132765453416200000, 132765129416213861, 132765453416200000: NG!
i= 1: 132765453416210000, 132765129416218094, 132765453416210000: NG!
i= 2: 132765453416210000, 132765129416218837, 132765453416210000: NG!
i= 3: 132765453416210000, 132765129416219530, 132765453416210000: NG!
GetLocalTimeやめたら? 時刻取得用のAPIをパフォーマンス計測用に使っちゃったんだね
WIN32では大昔からQueryPerformanceFrequencyとQueryPerformanceCounterを使うよ
https://docs.microsoft.com/en-us/windows/win32/api/profileapi/ >>393
GetLocalTime()の精度が10 ms台だというのは
Windowsのデフォルトのスレッドへの最大ディスパッチ時間15.6 ms(PCによっては10 ms)の影響が混入している可能性、
>>392のリンク先のような計測方法をとった場合、計測中に他のスレッドに実行権を横取りされたりすると、どうしても
期待する時間に対して15.6 msとか(高優先のスレッドが相次いでディスパッチされた場合はあるいはもっと)実際の時間が大きくなる
一方>>375の計測方法は時間の順序にのみ注目しており、プリエンプションの影響を受けない(はずだった
この話に猜疑があるなら後で述べる
>>392
>>392の情報提供はdクスやし実際乗り換えようかと考えているが、それはそうとして、std::chronoのふるまいを検証しなくて委員会? というわけでms単位のUNIX timeを得るにあたってstd::chronoとGetFileTimeAsSystemTime()が同じ精度であり互換であることを
直接検証すた、
https://ideone.com/9Opqj9
実行結果(Windows 10)
i=---: st1, chrono, st2: ORDER CHECK
i= 0: 1632049473157, 1632049473157, 1632049473157: OK.
i= 1: 1632049473158, 1632049473158, 1632049473158: OK.
i= 2: 1632049473159, 1632049473159, 1632049473159: OK.
i= 3: 1632049473159, 1632049473159, 1632049473159: OK.
i= 4: 1632049473159, 1632049473159, 1632049473159: OK.
i= 5: 1632049473159, 1632049473159, 1632049473159: OK.
i= 6: 1632049473159, 1632049473159, 1632049473159: OK.
i= 7: 1632049473159, 1632049473159, 1632049473159: OK.
i= 8: 1632049473160, 1632049473160, 1632049473160: OK.
i= 9: 1632049473160, 1632049473160, 1632049473160: OK.
NG times=0/10
問題無くなったやたー >>393
GetSystemTime()は確かに根本的に精度悪かったスマンカッタorz
この結果からすると、ウィンドーズのシステム時間のの実装は、
OSがプリエンプトした際に更新し、ディスパッチ中は値が変わらないというしくみな可能性が大きい
※ 取得時間の間隔が15.6 msの倍数にならないのは、15.6 msというのがあくまで1津のスレッドが
ディスパッチされてからプリエンプトされるまでの「最大」時間であって実際は高優先のやつに横取りされたり
自発的に待ちに入ったりで15.6 msより小さい時間で実行権をOSに返すからだと思う 古いWIN32開発者には常識的な話で検証の必要もなく、実際に検証用のプログラムは昔から大量に作られてるからだと思う
取得時間の間隔が15.6 msの倍数にならないのは「主に16ビット Windows との下位互換性のため」
https://docs.microsoft.com/ja-jp/windows/win32/sysinfo/windows-time >>400
後半って「Windows時刻」の説明だよね?
GetSystemTimeで得られるのは「システム時刻」であって、また別の時刻体系だと読んだけど間違ってる?
https://docs.microsoft.com/ja-jp/windows/win32/sysinfo/system-time
WinAPIスレに持っていったほうがいいかもな >>401
大元はWindows3.1時代からあったGetTickCountだと思うんだけど、説明的にそこしかなかったから書いた
WinAPIスレで聞きたければどうぞ 周期15.6 msを下位互換性のために新しいWindowsがエミュレートしているというのはありえない
1スレッドへの最大割り当て時間としての15.6 msはPCによって変わり得るデフォルト値にすぎないし、
http://hp.vector.co.jp/authors/VA007219/rtc_pic.html
だいたい設定でも変わるし、
https://atmarkit.itmedia.co.jp/ait/articles/1410/30/news150_2.html
(スレッドのクォンタムタイム)
取得間隔が15.6 msにならない理由は>>399で説明いしたし で、GetTickCount()の分解能かきちり1 msであることはビジーループ的に値をとってみたらワカル
分解能に関して後方互換性も糞もなく昔からそいうブツのはず
多分やけど、ハードウェアのカウンタを読んでるだけやからなあれ と思って、
const int N = 10;
std::vector<DWORD> vec;
DWORD curTmg = GetTickCount();
DWORD prevTmg;
while (vec.size() < (size_t)N) {
prevTmg = curTmg;
curTmg = GetTickCount();
if (prevTmg != curTmg) {
vec.push_back(curTmg);
}
}
for (int i = 0; i < N; i++) {
(差分vec[i] - vec[i-1]をprint)
}
というのをやったら、 vec[0]=1391507593
vec[1]=1391507609 (diff=16)
vec[2]=1391507625 (diff=16)
vec[3]=1391507640 (diff=15)
vec[4]=1391507656 (diff=16)
vec[5]=1391507671 (diff=15)
vec[6]=1391507687 (diff=16)
vec[7]=1391507703 (diff=16)
vec[8]=1391507718 (diff=15)
vec[9]=1391507734 (diff=16)
やったわorz
まつがえますたすみません;;;
勉強になるなあ、 >>402
自己レスです
GetTickCountとGetLocalTimeとGetSystemTimeの分解能調査
https://ideone.com/wKC8DA
1000回値が変わるのにかかった時間をマイクロ秒で計測した(std::chrono::high_resolution_clock::now()で計測)
PS C:\> .\ConsoleApplication8.exe
15614998
1003946
1000238
PS C:\> .\ConsoleApplication8.exe
15621414
1001066
1001218
PS C:\>
結論: GetLocalTimeは約1秒なのでこの環境(Win10+ハード)では1ms程度の分解能がある
感想: 誤差大きい スレタイも読めない、検索できないやつがまともなプログラム書けるはずもなく・・・ windows API使いたがるひとがいてめんどくさい
こっちはなるべく標準のc++使いたいのに プラットフォーム固有の話も参考になる
今回の流れは Win32 API と std::chrono の違いが端緒だしスレ違いというほどではない 私馬鹿よねーお馬鹿さんよねー今日も win32api とりあえず動かないから面白くないということなのかもなということで、Linuxのclock_gettimeにも対応しといた。
BSDとmac組は知らん。
https://ideone.com/Z9CfOo
一応WIN32はあえて低解像度のを計測してるという点だけは補足しておきます。 >>417
スレッドのスケジューリングも変化するので注意です。
tickとはそもそもそういうものでしたが。
http://archive.linux.or.jp/JF/JFdocs/The-Linux-Kernel-20.html
>>418
>>395でそう言ったし、high_resolution_clockで使用されてるのもそれ CreateWaitableTimerEx(NULL,NULL,CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,TIMER_ALL_ACCESS) >>420
そのタイマは同期待ち合わせに使用するタイマリソースですね
時間計測用に使うのは勿体ないのでやめましょう
また無言でAPIだけ書かれても困ります そもそもパフォーマンスの計測に使うなんて言ってなくない? >>422
この例はExついてないけど、こういう使い方をするものなんだよ。
待機可能タイマー オブジェクトの使用 - Win32 apps | Microsoft Docs
https://docs.microsoft.com/ja-jp/windows/win32/sync/using-waitable-timer-objects
>>423
>>388で求めているのは正確には時刻取得だね。つまりsystem_clockの話。
俺がしてるのは時間計測なのでsteady_clockの話。
違いは時刻の修正などにより増減するかしないかという特性の違いと、それを実現するHWタイマの分解能/性能の違い。
GetLocalTimeの分解能は文書にも記述がなく、>>393の指摘だけで事実関係が不明なまま宙に浮いてたので、>>416などでそれを計測した。
ここでは10〜15.6msの出元であるGetTickCountもついでに計測した。
steady_clockとsystem_clockをどこかで同時に取得して、steady_clockの分解能のまま時刻っぽいものを得るみたいなことも短期的には現実的な精度でできなくはないけど。 3種類ぐらいのタイマの時刻が1000回変化するのに要するトータル時間Tを測っているらしいが
この計測結果からSYSTEMTIMEの分解能がHWタイマの分解能/性能の違いに起因すると結論づけることはできない
実態は>>375な計り方でst1: SYSTEMTIME、now: nowtime_point、st2: SYSTEMTIME、の順で立て続けに時間をとると
>>388の通り
st1 ≦ now && now ≦ st2 + 1 ms
という結果なわけで、この「1 ms(<15.6 ms)というのは本当にハードウェアタイマの分解能なんかい話が違うぞ?!」と詰問されて
答えに窮する>>424な未来が見える見えまくり 実態は>>399に書いた理由のはずで、
証拠にst1の取得とnowの取得の間にSleep(1000)とか入れたら
>>388の結果はたちどころに
st1 ≦ now && now ≦ st2 + 1秒
に早変わりする
よってGetSystemTime()で取得するSYSTEMTIMEの分解能はHWタイマの分解能/性能起因ではなく、
GetSystemTime()で取得する時刻がOSのプリエンプションタイミングでのみの更新されるというソフト要因である、
という>>399に述べた理屈が正解ということでケテーイ
実際にやってはいないが天才なので以上のことはちょっと考えたらワカル ごめ、Sleep(1000)を入れたのではOSにプリエンプションの機会を与えてしまうからNG
正しくは
GetSystemTime(&st1);
15.6 ms未満のビジーループ <== 訂正
now = system_clock::now();
GetSystemTime(&st2);
とすると、
st1 ≦ now && now ≦ st2 + 15.6 ms
にnowの精度が劣化する、に訂正
OSのAPIもプリエンプションの機会にならない保証が無いのでビジーループはガチでビジーループで作る必要があり、
面倒なのでやらないがな! といいつつAPIに頼らずに10 ms規模のビジーループ(ビジーウェイト)させるのはやや技巧を要すると思ったので漏れが自らやってやった、
https://ideone.com/CjXN4X
※ 計測の実行は要Windows
結果、1 ms、8 ms、16 ms、1秒のどれに変えても>>388と同じで、
std::chrono::now()の時刻nowに対し、その直後にGetSystemTime()で得た時刻st2が
1 msだけ追い越されることはあっても決して 1 msより大きく追い越されることは無かったorz
なぜじゃ闇が深いなこれ、
もちろんGetSystemTime()ではなくGetSystemTimePreciseAsFileTime()を使う(↑のソースコードのPRECISE_AS_FILETIMEマクロ定義を有効化する
と>>398の通りドンピシャな時刻順になる点はビジーウェイトがあっても変わらない。
GetSystemTime()のふるまいが一方的に謎杉 WinAPIスレに持っていってくれますか?
結局<chrono>に固有の問題(?)ではなくて背後のAPI関数に関することって分かったはずなんで とか言いつつ自分で探してきたので貼っちゃう……
GetSystemTimeの分解能が15.6msというのはXPまでの話らしい
https://www.thedelphigeek.com/2007/10/calculating-accurate.html >>425
HWタイマの分解能/性能の違いと言ってるのはsystem_clockとsteady_clockの違いの話でWindows APIの話はしてないよ。
一応補足しておくとepochも違う(時刻としてそのまま使えるのはsystem_clockということ)。
>>426以降は妄想が迷走してるだけに見えるかな。
>>430は新しい事実で>>393の謎も解けたしもう俺的に不思議な部分はない。 > プリエンプションの機会
機会を与えないことができるのは昔のWindowsだろ 割り込み禁止命令が実行できたり
割り込みコントローラにコマンド出せたりする
デバドラかMODESETみたいのないと無理だよ std::complex<double> の変数 a, b について、OpenMP の並列リージョン内での
#pragma omp atomic
a += b;
が
error: invalid expression type for '#pragma omp atomic'
というエラーを出すんですが、std::complex はアトミック演算の対象外ですか?
それとも他の何かを見落としてる可能性がある? ompのAPI仕様書を読むと対象はスカラー型のみって書いてあるから対象外なんじゃないの? 数学とか物理の用語としては複素数はスカラーですが、コンピューター用語としては違うんでしたっけ? >>438
std::complexはclass型だよ。c++では >>441
つまりatomicはプリミティブ型だけ想定してるってことですかね
ありがとうございます
おとなしくクリティカルセクションにします >>438
C++ におけるスカラ型の定義
・ 算術型 (整数型と浮動小数点数型)
・ 列挙型
・ ポインタ型
・ メンバへのポインタ型
・ std::nullptr_t
・ 以上を cv 修飾 (const や volatile で修飾) したもの
https://timsong-cpp.github.io/cppwp/n3337/basic.types#9
言語によって定義は異なっている (または定義を持たない) ので
コンピューター用語として一般化は出来ないと思う。 ここはC++スレだからC++用語で必要充分だ
無理に一般化する必要はない 複素数が「算術型」じゃないのって冷静に考えるの結構奇妙だな 複素数を直接扱う命令がないCPUが多い以上、小数2個で表される複素数がスカラではないのは自然だと思うけど
それを言い出すと、一般線形群と呼ばれる行列はなんでも算術型になるのではないか?と思えてくるし arithmeticを「算術」とか仰々しく訳すからおかしくなる
要は小学生がさんすうで習うような単純な数のことよ ベクトルの係数になるんだから基本的にスカラじゃねえの 複素ベクトル空間の係数体の元として見ればスカラだし複素数体を実ベクトル空間と見れば複素数は実ベクトル 除算が定義できる体なので普通はスカラーとして扱うと思うけどな。
2要素の実ベクトルや2自由度の行列に適切な演算を導入することによって同一視することはできる。 >>447
要は小学生がさんすうで習うような単純な数のことを「算術」と言うんだが >>452
>2自由度の行列に適切な演算を導入
有名な a b -b a 以外にも複素数と同様に振舞う行列を定義できるものでしょうか?それはどんな形? 好きなX^2=-Iを満たす行列Xを用意すればaI+bXが複素数の表現になるよ >>454
> 有名な a b -b a 以外にも
> 複素数と同様に振舞う行列
この世のことを何一つとして理解してないことがよく伝わってくる2フレーズ 複素数z=x+iy (x, y:実数)とした場合どうやって行列で表現できるのか分からん
そもそも無理だろ 複素数の実行列表現あたりで調べれば出てくるから自分で調べろ。
複素数ライブラリの実装は行列表現だろ。 承認欲求が満たされなかったキチガイのハ◯ンが荒らしてるんだな >>460
キーワードありがとうございます!
1, 1, -2, -1 とか 3, 2, -5, -3 とか i に対応するものはいろいろあるんですね
>>456
生きていてすみません そもそも勝手な演算❎とかを用意して、それを複素数の演算になるような演算規則にすればいいだけの話
普通のプログラミング言語での実装は2要素ベクトルに対して複素数積となるような演算を*に対応させているんだと思うけどな
行列積が複素数の積と同一視できるような表現行列があるというだけ
群論とか環論とか体論とか入門的にでもやればわかるよ ベクトルの要素は座標変換で変わるからスカラーではない まつがえたorz
誤: 変わるから
正: 変化すっから んまーたしかに物理現象は座標変換しても変わらない(同じもの)とみなすのが
物理の先生なのかもしれん スカラーもそん延長線上の概念
しかし観測が系に影響を与えると言い出した時点でいつまで真理でありつづけることやら…… >>467
言葉足らずだったかもしれないが、複素数体と数学的にはR2の正規直交基底かつ基底の長さが1のベクトルの成分表示を、適切な演算を入れることによって同一視することができるという話をしているのであって、一般的なベクトル空間の話をしている訳ではない。 スカラーか否かというのは数をどこに使うかの話であって
数をどう表現するかの話ではないし、 それはそうとしてR^2と言っただけでは計量が入っていないから(平行移動も糞も無いため)ベクトル空間ではない
つまり { ベクトル空間 } ⊂ { R^2 } であってR^2の方がより一般的
R^2上で実数と同じ7つの演算則を満たす演算を形式的に定義することはできるが|i|=1を表すために
>正規直交基底かつ基底の長さが1のベクトルの成分表示
が必要になるから複素数体を正確に言い表すにはR^2ではなくてユークリッド空間か何かが要ることになるんじゃないの 加法(V × V → V)と係数体による倍演算(K × V → V)が入ってて線型ならベクトル空間だよ, 計量入れたら計量ベクトル空間 関数の引数に参照渡しで何も渡さないようにするはどうすればよいですか
自作クラスAがあったとして、それを引数にとる関数
void hoge(int& p1, A& p2)
があります。
ただ、p2は、ケースによっては要らない場合もあって、その場合にはどうすればよいですか。
調べてみたらnullptrみたいなのはあったので、
int p1 = 1;
hoge(p1, nullptr);
と書いてみても、
非constの左辺が何とかとエラーが出て、渡せませんでした。 >>475
参照は何も参照していない状態というのは作れない。
参照で受け取るように書いてあればその参照が無効ということはあり得ないという表明として解釈するのが通例。
(実際にはダングリング参照はあり得るけどそれは単に間違ったプログラムなので気にしない。)
引数として不要なのであればオーバーロードで引数が不要な関数も用意するのが真っ当な方法だけれど、
どうしても無効ということを表す状態を渡したいということであればダミーのオブジェクトを作っておいて
それを無効の意味に使うという方法は考えられる。 (不格好だけど……。)
#include <iostream>
struct A {};
A dummy;
void hoge(int& p1, A& p2 = dummy) {
if(&dummy == &p2) std::cout << "p2 is dummy" << std::endl;
else std::cout << "p2 is not dummy" << std::endl;
}
int main(void) {
int foo = 1;
A bar;
hoge(foo, bar);
hoge(foo);
}
あるいは std::variant と std::monostate と std::ref を組み合わせれば表現できなくもないかなぁ……。 hoge(p1,* static_cast<A*>(nullptr)); >>476
*(A *)nullptr にしないとエラーになるな
そいで関数側で&p2==nullptrでnullptrが渡されたかどうかチェックできるね
でもこんなの許されてるの? >>476 >>480
当然だけど (空ポインタを含めて) 無効なポインタをデリファレンスしたらその時点で未定義。 何いってんだ
キチンと動作する
ただの参照なんだから未定義じゃないだろ
他の変数に受け渡してるワケでもないし >>482
実質的な (コンパイルされた後の) 動作として値を取り出す必要がないというのは、
言語仕様上において * の適用を無かったことに出来るわけではない。
(C には単項 * の結果に単項 & を適用した場合に相殺されてどちらも無かったことになる規則があるが……。) また未定義動作なんか怖くない君か
命知らずなのはいいけどチームプログラミングには関わらないでね本当に迷惑だから 1. 参照をやめてポインタにする
2. std::optional<T>を使う(C++17以降)
俺ならこのどっちか クラスTが自作クラスなら
Tにnulを意味するlオブジェクトを定義すれば良い……
>>477なdummyオブジェクト方式はテンプレートの中で使いにくくなるいはず
>>485なstd::optional<T>案はどうせ余計な記憶を要するのだからT固有のnullを定義するうのとイーブン もちろんT固有のnull「値」の定義においては
オブジェクトの参照 == null値、
はアドレスの一致ではなく値の一致として解釈されねばならな
い さもないと、クラスTのnull値をT_NULLみたいな名前にしたとして、
T arr[] = { T_NULL, T_NULL, T_NULL, T_NULL };
みたいなことができないか
らな >>480,482
gcc 11 の -O2 で「&p2==nullptrでnullptrが渡されたかどうかチェック」はできなかった。
https://wandbox.org/permlink/c9QQIkFRPpFHd7rL void hoge(int& p1, optional<A>& p2 = nullopt) { // constじゃないのでエラー
みたいなことってoptionalで上手いことやる方法ないの?
呼び出し元は
int i;
A a;
hoge(i, a);
hoge(i);
みたいな感じで
書き換えられるけどhogeから抜けたら消える初期値nulloptのoptional<A>をデフォルト値で渡せるのか知りたい nullopt以外が渡されたらそのA&に対して、
nulloptが渡されたらスタックにAを構築したうえでそのA&に対して操作したい、ってこと?
それはvoid hoge(int& p1, A& p2 = デフォルト値)でいけるんじゃないかい >>493
やりたいことは std::optional<A>& ではなくて std::optional<A&> 的なことだろ。
しかし std::optional は参照を保持できないのでそういうときのために std::reference_wrapper がある。
コードにしたらこんな感じ。
https://wandbox.org/permlink/qEaoGDWFh7LmzE4m 部分特殊化できないのは関数テンプレートだよな
template<class T1, class T2>
struct test {
void fig1();
void fig2();
void fig3();
};
template< > void test<void, void>::fig1(); //ok
template<class T1> void test<T1 , void>::fig2(); //error
template<class T2> void test<void, T2 >::fig3(); //error
クラステンプレートなのに弾かれるのは何で? その部分特殊化されたtest(構造体)が定義されてないからだね
先にtestの部分特殊化を書けば通る >>494
std::reference_wrapperは知りませんでした
std::optional<A>をstd::optional<A*>にしてconstのままいじれるようにした気分なので
実質無理ってことなのかなぁと思いますが…
ありがとうございます >>475
普通はオーバーロードだな。デフォルトを指定させたいのならnullobjectを始めとする定数オブジェクトかね。
nullポインタとか空のスマートポインタとかはエラーの元だから避けたいところ。 >>497
自己レスです
いずれにしても呼び出し元を変更せずに要件を満たせそうな唯一の方法っぽいので解決ですね
(私は>>475ではありません) とはいえ、いきなりテンプレートにするのはハードル高いので、
結局は、継承クラスをいくつか作ってみてテンプレート化を試すことになる >>498
> 普通はオーバーロードだな。
これに一票 >>489
gcc7でも-O2つけるとダメだね
つけなきゃ一致するけど 最適化オプションの違いで挙動が変わるようなコードはそもそもダメだって理解してくれよ インテルコンパイラはもう規格満たしてないだろってくらい滅茶苦茶に挙動を変える
gccなら、最適化で結果が変わるようなコードはダメコードと言って良いと思う >>496
遅レスすまそ
testなら部分特殊化できるのはわかるんだが
その場合クラス定義の全部を書き直すよな
template<class T1>
struct test<T1, void>
{
void fig1();
void fig2(); //特殊化したいのはここだけ
void fig3();
};
fig1とfig3を一次テンプレートと同じ内容で
書き直さにゃならんかね 関数テンプレート内でラムダ式使おうとしたらコンパイルできない
template<class T> void hoge(){
auto func = [](){return 0;};
}
int main(){
hoge<int>();
return 0;
}
in instantiation of function template specialization 'hoge<int>' requested here
と出るが、何がだめなのかよくわからん >>509
そのメッセージは「関数テンプレートはここで特殊化 (テンプレート引数を当てはめて具体的な型に展開) されたやで」
というメッセージで、普通は他の警告やエラーの補足として出てくる。 なんか警告が一緒に出てない?
func が定義されとるけど使ってないという警告は出てくるけど無視して問題ない警告なのでコンパイルできないってことはない。
警告をエラー扱いにするオプションを付けてたりしない? >>511
C++20 では std::is_pod や POD の概念自体が非推奨になってるぞ。
次あたりでは廃止されるんとちゃうか。 あるラムダ式が他のラムダ式をコピーするとき、参照キャプチャにするかコピーキャプチャにするか迷うんですが、皆さんはどういう基準で決められてますか >>513
コピーキャプチャはコピーなので、それ相応のリソースを食う。
基本は参照キャプチャにしている。 破壊的代入の余地が無いようする
つまりコピーを第一の選択肢として考えるする *thisはさすがに参照にすることが多いが(だいたいコピコンがあるとも限らないし、
とはいえ参照コピーしてパラメータに対する破壊的代入を許すと思想的に重箱読みになって気持ち悪い気がするし、
参照渡ししたオブジェクトは一般にスレッドローカルとは言い切れなくなることから
スレッドセーフと断言しにくくなるというのは実害に数えて良いと思う
入れ子になったラムダ式の奥深くでそれをやられると、いつ排他制御すべきなのかが全くワケワカメになりかねない >>516
だとすると一番効果的なのは
C++でコード書くこと自体をやめることだな
あんたの場合は >>516
コピーキャプチャが第一選択肢という結論は分かるが
それ以外の説明が完全に意味不明 意図しない破壊を防ぐにはキャプチャしなきゃいいだけ
それを参照のせいにするゴミはプログラマの資質がない とりあえずで[&]で書いてるな
丁寧にやりたければ変数ごとに考えて明示する コピーのコストに無頓着なやつは11以後のC++に向かないな スレッド立ち上げるとかファイル書くとかクソ重い操作が伴う時にコピーコスト気にしてもしょうがない
場合によるとしか どこでも使う汎用性高いものなら問題が起きる前に[=]にしてる
逆に[&]はよほど安全だと思わない限り使わない >>522
スレッドセーフをどう保証するかに無頓着な香具師はマルチスレッドプログラミングに向かんわ
>>518、>>519
低レベルなレスどうも
ラムダ式の成り立ちを知らなかったり
どのように使われるか想像できなかったり
使ったこと無いんじゃね;;; >>525
スレッドがどうたらはおまえさんが勝手に言い出したことで元質問にはない
まさかとは思うがコピーしてりゃスレッドセーフなんて主張はしてないよな ラムダ式は一般にラムダ式を定義したスコープの外に持ち出され、予見できないタイミングで使われうる
参照キャプチャだと
(1) ラムダ式が使われるタイミングで参照xの参照先が存在することが保証されていなければならない
(2) ラムダ式が使われるタイミングで参照xの参照先へのアクセスが他のスレッドと競合しないことが保証されていなければならない
とゆー2条件をクリアする必要がある。
コピーキャプチャだと(オブジェクトがディープコピーなら)どっちの配慮も不要
参照キャプチャして(1)、(2)を満たして安心できるのは、イミュータブルなオブジェクトだけ……! >>526
ラムダ式、が含意する事柄について不十分な理解なレスktkr、
危険プログラマー認定のレベル3ぐらいやな;;; >>527
ラムダ式をスコープ外に持ち出すなんてレアケースを「一般に」とか言われましても 遅延評価されるものはよくコンテナに入れて後でぶん回されるから・・・ >>529
定義するのと使う(評価する)のを同じスコープ内でやるならラムダ式使うまでもないじゃん?
ていうか使うまでもないんですよ
>>529はアレな人? スコープ内の変数をキャプチャする処理をスレッドで動かす場合は普通にラムダ式を使うと思うが。 >>531
はぁ?お前これしないの?ラムダ式のユースケースって9割方この類だろ
std::functionに突っ込んではるか遠くにぶん投げたりコンテナに詰め込んだりするのだけがラムダ式の使い道だと思ってるの?
std::sort(v.begin(), v.end(), [](int a, int b){/*...*/}); みなさんスレッドセーフにしたいときはスレッドセーフになる様に書きましょう 任意のスレッド安全性を実現するのはゼロコストでは不可能だから
必ずシングルスレッドで実行される保障がある場合などはあえてスレッド安全性を捨てることもある std::conj() に double を渡したら std::complex<double> にキャストされるのが嫌なので、double を渡したら何もしないで double を返し、std::complex<double> を渡したら std::conj() と同じ動作をするオーバーロード関数 conj() を作ろうかと思うのですがアリですか?
なぜ std::conj() がそういう動作じゃないのか不思議で、何か見落としてたら教えてください こここ・・こういうこと?
(A)キャプチャが必要でスコープ内で実行までされるケース
(B)キャプチャが必要でスコープ外まで実行が遅延されるケース
(B-1)ラムダ式生成時と実行スレッドが同じケース
(B-2)ラムダ式生成時と実行スレッドが違うケース
(A)なら全員「[&]で問題があるケースはない」と考えている
(B-1)は好みが別れているところ
(B-2)は好みが別れているところで、さらにキャプチャされる変数側をスレッドセーフにするかどうも好み
[&]と[=]がよく分からない人はコチラ
https://ideone.com/OQS113
以下個人的意見
スレッドセーフにするコストは結構高い(開発・実行・保守全てで)ので、競合させずに遅延可能ならそれに越したことはないと考えている
ようはコピーするコストをそれほど高くは見積もっていない >>538
おまえさんの論法では同時並行はすべて別プロセスにすべきってことだな >>540
う〜ん、伝わらないですね・・・
共有リソースに競合するアクセスがなければ排他制御の必要がなく、スレッドセーフにする必要がないってことです
そもそもコピーして共有しないことで排他制御が必要なくなれば、スレッドセーフにしなくていいという考え方ですよ だから共有=リスクなんだろ?
もうマシンも別の実機にすれば最強防御じゃん >>542
残念ですが理解してもらうことは諦めます >>533
頭の中がgdgdな人が話をgdgdにしようとしていまつね……
std::sort()の呼び出しと同じスコープが終わった後に
[](int a, int b)が呼び出されないということは、単にstd::sort()がreturnするまでにラムダ式を忘れてくれる作りだから(たまたま)担保されているだけであって、
[](int a, int b)のスコープが限定されるために担保されているわけではないし、
[](int a, int b)がラムダ式だから担保されているわけでもないの。
つまり、>>533は
>ラムダ式をスコープ外に持ち出すなんてレアケース(>>529)
の根拠に全くなっていないワケ レアケースがどうこういったところでレアケースなら考えなくていいってわけでもない。
そんなの個別の事例ごとに考えるしかしょうがないだろう。 >>543
無理筋の主張ってことがわかってもらえたならいいよ >>546
無理筋ではありませんよ
スレッド以前から並列処理で共有される実行コンテキストを分けることは大昔からやられてきました
今更その手法自体を想像できない人に、こんなところで説明するのは困難なだけです おまえさんの言う「大昔」がどのくらいか知らんが
俺が若手の頃はRENT,REUSなんてやってたよ ラムダ式によって作られたオブジェクトがキャプチャされたオブジェクトより長生きする可能性があるならコピーキャプチャ
そうでなくともレジスタに乗ると思われるならコピーキャプチャ
そうでない場合に初めて参照キャプチャ
排他に関してはshared_ptr<mutex>とshared_ptr<なかみ>をメンバに持たせてコピー可能にしつつ、メンバ関数経由で排他制御するのが筋だと思う
RustのArc<Mutex<T>>パターンに影響されすぎかもしれないが……
いずれにせよキャプチャと排他制御の問題とは切り離して考えることができるし、そうすべき ラムダ式関連でいうと参照とかコピーをデフォルトだけで指定したときも実際に使ったものの分しかクロージャオブジェクトのサイズに乗ってこないと思ってるんだけどヤバい? >>550
むしろ他に何が乗ると思っているのか?
気になるなら生成コード見て確認すればいいだろうとも思うし。 >>548
大昔とは1990年頃の話です
COBOLなのか知りませんが、reentrantとreusableは今回の話と直接関係ありません >>551
cppref見たらクロージャオブジェクトのサイズは未規定とあって気になった >>552
関係大ありだよ
あの当時はアセンブラでC++は使ってなかったというだけだ
わかってないのおまえさんだな >>554
説明するべきでないのが残念ですが、その頃からあなたが分かってなかっただけですよ >>555
おまえさんがどう思おうと勝手だが
センターオウンコーディングとかやってたよ
マウント取られる気が全くしねえぜ >>556
マウント取る取らないとかどうでもいいです
あなたが理解できないのをどうにもできないだけなんです クラスの型を自動変換して関数に入れるにはどうすればいいですか?例えば、
class A {
public:
double hoge;
};
class B {
public:
int hogehoge;
};
int function(A aaa);
があった時に、functionにB型を入れても動くようにしたいです。
クラスAのソースに、Bから生成するコンストラクタ書ければいいのかもしれませんが、
実際はAはライブラリのクラスで触れなくて、Bが自作のクラスになります。 >>560
Bを受け付けるfunctionを書くんや B extends A
としたら
function
の引数をキャスト?で動かない? 簡単や
template<class A>
int function(A aaa); できました。ありがとうございます。
また、ポインタのvectorを実体として使うにはどうすればよいでしょうか?
std::vector<A*>
で定義されてるものを、
std::vector<A>として使いたいです。
別のvectorにポインタ値を詰め直せばいけると思うのですが、元のポインタの場所のまま実体で使いたいです。無理でしょうか。 reference_wrapper使うんや
まあ下らんこと考えんほうがええ >>564
ややこしい所有権・所有責任問題が発生するから、ソースコードを見直したほうがいい。
具体的にはstd::vector<*A>を
std::vector<std::shared_ptr<A>>
にして、shared_ptr<A>をやり取りするようにすべきだな。
性能問題とか互換問題とかでも無ければvector<*A>なんて使うもんじゃない。 言ってることは同意だが、ポインタの型もまともに書けないような人に言われても説得力がない 簡単や
std::vector<std::shared_ptr<A>> ドラクエ3のバージョン違いの謎に迫る!
https://www.youtube.com/watch?v=sh5GXYs6T1c
2021/10/01に公開済み
FC版DQ3には、AバージョンとBバージョンが存在する
今回はROM内のプログラムを徹底比較!
どこが違うのか白黒ハッキリさせると息巻いた内藤プロ
当時自分が作ったのに全て忘れてて大変なことに・・ ぶっちゃけ継承とかポリモフィズムはオワコンでテンプレート最強? >>573
過去の C++ の流行においては継承が強調されすぎたこともあって
継承の害悪な面も見えて大幅な揺り戻しは有った。
しかしそれぞれに役割があるのでどれかが廃れるとかいう話ではない。
バランスとしては継承が控えめになったけれど、だからといって継承のない C++ はありえない。
結局のところそれぞれを適切に使えというだけのこと。 継承が有効に使われている事例をひとつも知らないヒヨっ子丸出しな質問だな
テンプレートの何がいいのかもわかってなさそう >>576
virtual使えないor使わない処理系で、使ってみたけど確かに頭にスッキリ入らんパターンだわw
あれはあれでポイントで使うと便利だし、反対にやっぱvirtualも便利でいいよねーとか。 >>573
メソッド共通化を実現するための継承はオワコン。
プレースホルダーを用意するための継承は現役。
総称型が実装されれば継承自体をオワコンにできそうな気がするけど、総称型風スマートポインタて無かったっけ? ○○なんていらねーよ害悪だけだ
まだ使ってるやつは全員バカ
これからは△△を使うべきだ
なーんて言っちゃってマウント取った気になってるおめでたいやつ
メガトン級にアホにされてることに気付かねえよな vector を shuffle する場合について質問です(gcc/windows10でテスト)
vector<int> vec(50, 0);
for(int i = 0; i < 10; ++i) vec[i] = 1;
random_device dev_seed;
mt19937_64 mt(dev_seed());
shuffle(vec.begin(), vec.end(), mt);
で確かに shuffle されているのですが疑問点がいくつかあります
1.dev_seed()が毎回同じ値を返してる?
(random_deviceの使い方を間違えてる?)
2.先頭の値が1に偏ってる?
(shuffle() を数回繰り返す解決方法もあるようですがあまり気持ち良くないです)
3.そもそもforで先頭の方に1を入れる発想が良くない?
(shuffleされてるならこれは関係無いと思いたい) ああこれか
https://cpprefjp.github.io/reference/random/random_device.html
>GCC (MinGW): GCC 9.1までは擬似乱数生成器 mt19937 を用いるため使用を推奨しない。詳細は備考欄を参照。GCC 9.2からは暗号論的な乱数である rand_s を使用する。 random_deviceがダメな環境でrdtsc命令使ったことあるな
良いやり方かは知らん >>589
前者は編集者による解説なども含んでいて仕様の意図や習慣がわかりやすい。 実装の現実みたいな補足もあるし。
後者は仕様書の再編を指向してるから正確だけど規則の羅列を読むのがしんどいこともある。
適宜使い分けて。 今までJavaでやってきたけどC++もやってみたいんだよね
すぐ出来るようになると思う? >>594
ならない
C言語のポインタや文字列について勉強したほうがいい >>594
c++でちょっとした文字列パースして内容に応じたオブジェクト構築する処理書いてたの、
ほぼ使ったことないJavaに移植したらスゲー早く出来てワロタ。C#もサクサクできたな〜
逆は色々イラッとするんじゃねぇかな? 元々C++はその辺の文字列処理を毎回1からゴリゴリ書くような言語じゃなくて何らかのライブラリを利用するものだと思うけど、
クロスプラットフォームで各種文字コードが自由に扱えて、c++11以降の仕様に対応してて、かつかゆいところに手の届くライブラリって意外とないんだよね
いや、俺が知らないだけかもしらんけどw >>596
std::regex使ってようやっと、かね。
c++はいつまでたっても文字列処理苦手なままだわ。 あれ出来上がるバイナリ重すぎなんだけど、今は違ったりするのかね Debugだとバカデカくなるけど
Releaseは気にならないレベル
(DLL除く) std::regexと等価なインターフェースを各々の正規表現ベンダーが用意してくれればいいんだが、それすら実現されていないお寒い状況 >>599
その辺も無いわけじゃないんだけど、クラスの構造どうしようかとか、メモリ管理どうするかとか、
変態trmplateでパズルしてみようかとか、選択肢多い分考えることも多い部分で時間かけることが
多い所はあるなーって。それがC++使いたい動機の裏返しでもあるんだけど。
あと本人の問題120%だが、ボケて油断してると、エラー直すのにやたら時間かかったりで。
Javaとか詳しく知らん状態だから言えるのかもしれんけど、もうこうするしかネェってレールが
最初からあるような印象でした。つかオラクルのライセンス問題のほうがムズいw std::regexみたいな文字コードというものがあることを知らない人間が作ってそうなものを標準だと思ってつかうのはやめたほうがいいと思います char8_tが導入されたんだからutf-8しばりでいいじゃない なんか最近曖昧な上に突っ込む点多すぎる内容的にはどうでもいい話題が多くない? >>607
utf8限定ならそこそこ。
もうutf8がデファクトだから、内部処理はutf8に統一した方がいいよ。 >>608
内部コードは utf-32 でやっているので、utf-32 縛りのほうがうれしいです‥ >>611
はぁ?
std:::basic_regex<char8_t>、std::basic_:regex<char16_t>, std:::basic_regex<char32_t> のどれでも好きなの使えばいいじゃん ところで、char16_t、char32_tってエンディアンはシステム依存しばり? ちなみに、いま使えるみたいですよ。
むかしは使えることになってるのに実際は使えなかったんだけど。
自作イテレーターにも対応してるようです。
アップルは知らんけど。
Ubuntu+gcc、Windows10+clでは自作イテレータでstd::regex<>が使えました。
これは、HTML、XML、JSONのデータ構造からコンテンツ内のみを検索のような事に使えます。
標準から外れるような議論もあるそうですが、便利なので外れないように抗議していきましょう。 C++20でchar8_tが入ると便利になりますよね。 >>613
規定しない
なのでそういうのはそこでは気にしない STLはセントルイスの略。
では、GCCは何処でしょう? 平面3リンクマニュピュレータの逆運動学のプログラミングが分かりません。
キーボードで手先の位置を入力すると、関節角が表示されるようにしたいです。
scanfを使うのと、アームの長さなどは適当に決めていいという条件です。
わかる方いたら、送って欲しいです。 >>619
どこの大学のなんていう授業か教えてくれたら送ってあげる >>619
冗長マニピュレータで一意に求まらん。制約条件設けてるはずだが。 >>622
リンクの長さは良さそうな値を定義してください。関節の座標はこちらで決めずにあくまでも手先の位置・姿勢であるxed、yed、φedから計算で出します。解が複数出てくるので、全ての候補を求めてください。
例えば、リンクの長さは根元から順に0.3m、0.3m、0.05mなどで良いです。
プログラムとしては手先の目標値を入力して、θ1、θ2、θ3が出力されればOKです。 >>622
目標値は、x=0 y=0.3m φ=90degがいいと思います。先ほどのリンクの長さの設定値で楽な姿勢でロボットの手が届く範囲ですので。 >>623
手の姿勢まで指定してて >>619 と違う問題になってんじゃん。どんなテキストにも解法載ってる問題丸投げしてんだな。 >>625
テキストに載ってないからここで質問してるんですよ。手の姿勢は例えばの話ですよ。どっちみちscanfで入力するんですから。 >>626
問題が違うっつうの。
ロボット工学のテキストには必ず載ってる。よく読めアホ。 >>627
日本語分かる?プログラムは載ってないから。教科書に載ってるから見ろって丸投げしてんのどっちだよ。 答える価値がないと思うなら放置しろよ
くだらねえ煽りやってんな迷惑だ >>628
プログラムが載ってるわけねえだろ、アホ。
載ってんのは**解法**(>>625) > どっちみちscanfで入力するんですから。
このレガシーさには誰も何も思わんの?笑 ssfanf_s()を使った方が(%sとかについて)ちょっと安全 わざわざC++なんか使っときながら勉強不足でモロアンチパターン踏んでるバカ
よくいるよね やっぱ普通fgets()して1行全体を読み込んでからstrtok_s()使いマスヨネー 文字列の数値化はstrtol()、strtoul()、strtof()、strtod()をオーバーロードしたwrapper関数を呼ぶテンプレートにすれば
cinと同等の型安全性と同等以上の使い勝手が実現にできるし、 C++な人ってゴリゴリ自分でBNF的なparser combinator書くイメージだな
わざわざcstring使う人はいない気がする いろんな人の手を経たプロジェクトだと CString(Windows) と std::string
(ていうか正確にはstd::basic_string<TCHAR>)が混在しがちなのがほんのちょっと悩みどころ えーっと・・・cstringはC言語のstring.hのことだよ しらそん
いちいち
#ifdef __clusplus
# include <cstring>
# include <cmath>
#else
# include <string.h>
# include <math.h>
#endif
みたいな書き方するん会、 json文字列として入力データを受け取って既存のjsonライブラリでパースするのが無難じゃないですかね C++でfgets使うアホの世界チャンピオンがいるな 壊れても居ないものを直そうとするヴァカに言われたくはないし、
行の長さが定まっていないみたいなアフォな外部データ設計でない限り
fgets()で軽くて十分 今ならメモリ不足とか気にする必要はほぼないから、
fgets()よりも、テキストファイル全体を一気に読み込んで1行分をstring_viewで返していく、みたいな流れの処理の方が効率は良いはずだよね MSVCのfgetc()とfgets()は実行速度が遅い >>646
ちゃうちゃう、目新しいという以外にメリットも無いのに飛びつく誰かさんの方
>>647
行の長さが定まっていない仕様というのは大変恐ろしいことでありまして、
40TBの入力も許容するという意思表明なのであります こと外部データに関しては、読み込み終えないとサイズがわからない、みたいな仕様は悪手
で、異常な入力に対してエラー出力するプログラムは正しいが
クラッシュするのはバグ
という観点からすると、動的メモリ確保による不定長読み込みができると言っても活かしようが無く、
結局fgets()でいいやん?となる fgets使うくらいならOS固有の関数を呼ぶべきだと思う
readとかReadFileのことね >>652
バッファリングを自力で実装するんか……
デバイスドライバ側である程度何とかしてくれるケースもあるかもしれんが 真理情報:fgets()はUTF-16やUTF-32のテキストファイルを正しく読み込めない ワイド文字用の関数は使っちゃだめということ?
まあ使い方よくわからんけど HTMLなりXMLなりJSONなりそれぞれパーサーがすでにあるのだからその恩恵を享受するのがナウなヤングの取るべき道でしょ >>652
俺ならCreateFileMappingを使う
fgetsなんて頭の更新が止まった昭和時代の化石のうちでも地頭までひどいやつの使うものだな >>656
ワイド文字は環境によってUTF16だったりUTF32だったりで仕様が定まらないので使いにくい >>658のような勝手にmmap使っちゃうようなのがいるとバグだらけになるよ Java、Python、Ruby、Javscriptなどの他言語にファイル読込み処理を移植する徒労を考えないバカが集うスレはここですね >>ID:NekA8urB の丸投げ君、己の課題であることを伏せて、お題スレに出題! 組み込みに近いところいると、大抵自炊に近い状態になるわ。
たとえばiostreamコンパイル通るやん、ってリンカがフラッシュ容量超えを宣告しやがる(フラッシュが640KiBもある豪華マイコンやで)。
上の方でrandom_deviceカスタマイズするの簡単にでけんやん、とか。ハード乱数なんて別にクラスに押し込んでも意味薄だけど。 >>661
他言語に移植するかどうかはおまえさんが決めることじゃないよ
プログラム技術板で下品な言葉に頼るのは低脳の証明だぜ C++の標準ライブラリを使用しない前提でファイル読み込みを考えるならOS固有の関数を呼ぶべきって言ってるだけだよ
C++の標準ライブラリを使用しないでCの標準ライブラリ呼ぶには何か正当な理由がいると思う 標準ライブラリのストリームは遅延評価やらなんやら余計な思惑が付いてるのでとにかく重い。 >>666
<cstdio>はC++標準ライブラリの一部だよ readもfreadもposixじゃろうよ
変わらんよ APIならサクサク快適。
1Gbps/s出る。
標準ライブラリは500Mbps/sくらいしかでない。 システムコールと言いたかったんだろうよ。察して差しあげろ >>668
C++からCの標準ライブラリを呼ぶならこちらを使えという意味
>>670
そういうのは具体的な根拠の提示が必要 >>660
mmap+おまえさん→バグ
という化学反応みたいなもんか fgetsはバイトを扱うのか文字を扱うのか分かりにくいよね
Javaはバイトを読むInputStreamと文字を読むReaderに分かれてる
ファイルは当然文字だからInputStream、上位のReaderで文字コードや改行コードを加味する
Cはバイトも文字もchar[ ]で扱うからAPIもバイト扱い・文字扱いが混在してる
fgetsは改行コードで区切るからバイトではなく文字を扱う関数のように思えるけど、実際は文字コードなどは考慮されないのでバイト読み取り程度にしか使えないしワイドキャラクタも扱えない
中途半端だと思う >>676
時代背景も考えずに中途半端とか言われても… まぁ、欧米の毛唐どもにもようやく必要性が理解できたchar8_tの導入が進めば文字コードはutf8に統一されていくとは思うけど、
utf8はutf8で冗長コードの問題があるからな…その辺のルールも統一しとかないとバグが量産されることになるな 2021年になってもテキストファイル読み込みの話をしなければならないC++の哀しさ ifstream とか
#include <iostream>
とか観るとダサいなーとしか思わない Windowsのcode pageのような列挙型と文字セット判定クラスがC++で標準化されてないとテキスト読み込み処理を標準化できないでしょ
文字セット判定クラスは既存の判定ライブラリも標準インターフェースを介して使えるように的な C++ではなくCを使うというならまだそいつなりに筋が通る可能性があるが
C++でfgetsにしがみつくのはC++のライブラリについてこれなかっただけの
無能の中の無能だ C++でファイル操作にcstdio(というかFILE*)を使うべきだと宣うなら
せめてその場合の例外安全性くらい論じてくれないと話にならな >>658
Create !
File !
Mapping !
なんでテキストファイルを読み込むだけのためにそんんあ牛刀(しかも移植性が乏しい)を使わねばならんのじゃ……
だいたい標準ストリーム(istream/ ostreamでも良いが)との結合はどうするんじゃ……
std::streambuf派生クラスとか自力で書くんか……
やっぱ頭にうんこ詰まってる人からはうんこしか出てきませんね…… >>686
fgets()の使用はC++についていけなくてしがみついているのではなくて、
天才の判断である >>688
あーおまえさん、あのAPIをベアで使ってるのか
ご苦労なこったな
C++使ってんのにクラス化って発想ねえのか >>687
>例外安全性くらい論じてくれないと
cstdioの仕様は突っ込んで調べてはいないがファイルの読み書きに関して
例外をスローすることがあるとしたら改悪で大層な失敗ライブラリとしか言いようが無い
ていうか例外安全というのは眉唾な概念でありまして、
40TBまでメモリを食いつぶしたら例外をスローするが
39.9999TBまでメモリを食いつぶしても何も起きないというコードは
システム全体の動作を担保できておらず設計したとは言えない
もっと定量的にプロアクティブな処置を講じるべきで、システムの正常動作を例外に依存させる設計は無い >>690
ますますのうんこ発言ご苦労
で、標準ストリーム(istream/ ostreamでも良いが)との結合はどうするんじゃ…… この議論の中で自作クラス推しはポエミーすぐる
やっぱうんこ製造機な人は仕方が無い >>892
おまえさん他言語への移植がどうたら言ってた? C++でクラス作るなって
Cで関数作るなに匹敵するすげえ主張だな
最長不倒main関数とかw Cだけやたら詳しくてクラスの仕組み知らないウン古参とか居るからな C++からCにソースコードを移植せざるを得ないことがあるから、Cプログラマでもクラスやテンプレートの知識は必須でしょ cの場合ファイルでクラスを実現するわけだけど、その縛りがある方がきれいになるよね twitterでCやC++を検索したい時、検索ボックスに
(C 言語) OR cplusplus OR cpp OR @i -@i lang:ja
と入れると割りといいことが分かった。
さらに、検索ボックスの右にある「…」のボタンを押して「検索を保存」しておくと、この検索文字列が勝手に消えない。 ::fgetsってstd::getlineに対するメリットある? getlineがそもそも遅くてダメ
fopenからのfread一択 $ man 3 getline
...
BUGS
There are no wide character versions of getdelim() or getline(). fopen/fread/fseekだと2GBを超えるファイルが扱えないよね >>706
fread()は2GB制約なく扱えるのでは? >>708
環境によってはそういう実装もあるだろうけど、保証はされていないはず
実際MSVCのランタイムとかはダメでしょ >>710
「ダメでしょ」っていう無駄な煽り質問じゃなくて、fread()の制約について触れたブログのURLとか教えてもらえますか? >>699
>C++からCにソースコードを移植せざるを得ないことがあるから、
いまどきそんなのある?思いつかない。 >>691
違うよファイル読み込み以外の場所での例外発生時にFILE*をリークさせないための設計の話だよ
君が何も考えてないのはよく分かった 書いてから気づいたけど >>714 は、見つからねンだわ、のほうがよかった MSVCのランタイムでfread()が2GB越えファイルを扱えないって話のURLはどこですか? >>716
スコープを抜けたらファイルをクローズしてくれるから安全、と考える
藻前の考えが浅いのもまた明らかだ
システム的にファイルをぶち切られること自体が致命的だったら?
また、クローズがエラーになったとき何が起きるか
(ただクローズするだけのクラスならエラー通知先は無い。例外を飛ばしたら即パニック
というわけで実用的なリソースリーク対策はコードの追加を伴うから
fgets()にリーク対策するのと言うほど違いが無いワケ 例外安全はやれるならやった方が良いのは認めるが
他人様が作ったライブラリの中に生ポをメンバにもつクラスがあったら穴ができる
まだこれぐらいなら静的解析で発見できるかもしれんが
上で述べたようなcloseのエラーチェックのスキップとか循環参照とかは機械的検出が難しい
例外安全に予期せぬ事象が起きたときのセーフティーネット以上のことを気体するのはソフトウェア工学的ではない
というわけでやっぱfgets()を使いつつ例外を起こさないように書くのに比べて言うほどマシでないワケ 君が例外安全というものについて何一つ知らない事はよく分かった
無知は罪じゃないから今から勉強し直そうね
知ってるふりしていい加減な付け焼き刃の知識を振りかざすのは恥ずかしいだけじゃなくてお客や同僚に迷惑を掛けるからね コードや証拠もなしに噛み合わない話の空中戦とかするくらいなら反論しなくていいから黙ってよう
どちらが正しいかはみんな分かっているのだから cout << sizeof ftell(nullptr); 馬鹿は正当性を定義も証明もできない事柄に正当性を見出してしまう好例
例外安全に予期せぬ事象が起きたときのセーフティーネット以上のことを気体できないというのが真実
それが証拠にいい加減でない知識として>>721以外の何があるのか>>722は示せていない
起こることが既知なら対処を平にコードに書けば良いのに
コードに明示されておらず、検証もしきれない実行パスをボコボコ作っといて安全と言い張る神経、 ていうか知能の問題かもしれん……
>どちらが正しいかはみんな分かっているのだから
衆愚の言い草
「何が」例外安全なのかきちんと定義してから出直してホスイ、 5chは煽ると答えが返ってくるという都市伝説があるらしい バグ報告する場合は再現条件を提示する責任がある
再現できなければ「おま環」で放置される
もしかしてこのスレの住人は、立民とか共産党の支持者だったりするの?
挙証責任って概念を知らないかな
モリカケ・桜を見る会問題にのめりこむような人は技術系の職業に向いてないから転職したほうがいいね 最後の一文、それを断言できるのはその問題にのめりこんでる証拠のような・・・ お前は泥棒をしたのだから泥棒したことをお前自身が証明しろ、と言いがかりをつけ続ける取調官とか怖いだろ
それと同じことを一部の本スレ住人や立民共産信者は言ってるわけだよ モリカケ・桜を見る会問題にのめりこんでいない人は
突然無関係のスレでモリカケ・桜を見る会問題の話題を出さないからね
常に意識している(のめりこんでいる)から技術系のスレで政治的な話をしてしまう 陰謀論など思い込みの激しい人は正義感でやってるから周囲の忠告に耳を貸さない
信者同士が共鳴しあうエコーチェンバー効果 「最近、この沼にはまって抜け出せなくなる人が多いんだよ、困ったものだね」と言いながら沼にはまっている人↑ MSVCでfread()が2GB以上のファイルを扱えないことを証明してくれさえすればいいんだよ、簡単だろ? 自分は雑なバグ報告しておいて、相手には執拗に問題解決を迫るキチガイとかイヤだろ? そもそもfreadと何をどんな環境で比較して結果どうだったなどの証拠がない件 正直興味のない話なので関わらなきゃいいじゃんって言われるだろうけど
「相手には執拗に問題解決を迫るキチガイとかイヤだろ?」と行っている本人が「証明してくれさえすればいいんだ」と迫っているところを見る限り
やっぱり本人も沼に入っているのに気づいていないんだな、と感じる小雨が降る今日この頃 いまさら何言ってんだ?
このスレは、ダニング=クルーガー効果でイキったバカをからかうためのスレだぞ スレタイトルのとおりC++に関する相談をするためのスレですよ
ID:L2ZQN19z7 は他人を煽るためだけに書き込んでるように見えるので少し風当たりが強くなってるだけです マイクロソフトのような大企業がfread()の致命的な不具合を永年にわたって野放しにするはずがないという常識や判断力すらない人は、いろんな陰謀論にハマるだろうね
ご本人はそれはそれで楽しい人生なんだろうけどIT技術者としてはどうかなって話
ま、反ワクチンの医者もごくまれにいるから、陰謀論にハマる人はどんな業界にもいるんだろう ビル・ゲイツがワクチンの「狂った陰謀論」を改めて否定 | Forbes JAPAN
https://forbesjapan.com/articles/detail/39513
2021/01/28 12:30
マイクロソフトの共同創業者でビリオネアのビル・ゲイツは、パンデミックを受けてSNS上で拡散した、彼に関する陰謀論の多さに「非常に驚いている」と述べ、ワクチンの普及の妨げになりかねない誤情報への懸念を示した。
ゲイツは1月27日のロイターの取材に、彼と米国のコロナ対策のトップであるアンソニー・ファウチ博士についての「狂った陰謀論」は、パンデミックに対する恐怖心とソーシャルメディアの台頭により引き起こされた可能性が高いと述べた。
パンデミックに関する最も目を引く陰謀論のいくつかは、ゲイツが「世界の人々にマイクロチップを埋め込むためにワクチンを活用しようとしている」という、根拠のない主張に基づいている。
ゲイツは、人々が本当にこれらの陰謀論を信じているのかどうかを知りたいと話した。「それは、人々の行動をどのように変えるのだろう? そして、我々はどのようにして、これを最小限に抑えるべきだったのだろう?」と、彼は問いかけた。 Microsoft、不具合修正一年くらいかかったよ 2000年ごろのLinuxユーザーなら、ゲイツがワクチンにウィルス仕込んでると大騒ぎしてただろうけどな。 >>732
ご指摘の動作は弊社ソフトウェア製品の問題点であることが確認されました。
引き続き調査を行います。
進展状況はID2273405でご確認できます。
今後も弊社製品ご愛顧のほどよろしくお願いします。 >>732
「証拠はあんのか?おお〜ん?」と言ってる晋三が暴力団に見える。
証拠がなくたって傍目に明らか。
なんで5000円でスイートに泊まれるわけない。
嘘つかずにごめんなさいしたら良かっただけ。 >>752
5Gにつながるためにもちゃんとワクチン2回打てよ
11月になったらワクチン接種会場がさらに減るぞ 違います
今後の心配は園遊会やお正月などのお食事会にモェ呼ばれるのか、という点です >>729
RAIIだから例外安全、と言うのは短絡的
文盲に読み飛ばされたのかしらんが>>720と>>721において
@ オブジェクトが個々に盲目的にリソースを解放するのが常に安全と言えるか?
A リソース解放時にエラーが生じたものを無視しておいて安全と言えるか?(あるいはコードの追加無しに無視せずに済む方法があるか?) B リソース解放を解放しない瑕疵があるオブジェクトの混入が無いことをどうやって保証するのか?
という3つの問題提起をしているのに対して、あいまいに取り繕って逃げたのが>>722
@〜Bに定説が無いとすれば(実際無いのだが)、例外安全というのは信奉する馬鹿の数だけ定義があるという話 盲目じゃねえし
uncaught_excptionsも知らんようだな
って言うとにわかで調べてシッタカこくんだろうけど
今の今までおくびにも出さなかったことで
どの程度の野郎かは察しがついてる だいたい火災で炎上するビルの8階から人が飛び降りたとして、
例外安全とやらでできることはせいぜい人を地面に軟着陸させて生命を守るぐらいの話で、
ビルの火災を消化はしないし(それをやるのは消防署
消化後のビルを復旧はしないし(それをやるのは各種の工事屋
復旧した8界のオフィスに飛び降りた人を戻して業務を再開させることもしない(それをやるのやEmployer
普通の人はまず火災を防ぐことを第一に目指すのだが、
例外安全主義者はそんなスタイルを古いと言い、例外安全に作っとけば安全と言い張るのだ 全然関係ねえよ
マジでビルから飛び降りて氏んだら? >>759
@〜Bのどれにも掠りもしない反応
(を出したことによって知能程度に察しが付く でfgets()に戻るが、以下のコードの例外の捕捉のコストは話の本筋ではないので無視していただきたいのだが
(そのコストが気になるなら「スコープを抜けたら閉じるFILE*」みたいなブツを作ったらfclose()のエラー処理以外は同じにできる)、
void foo() {
FILE* fp = fopen(...); // fpがNULLだった場合のチェックは記載省略
try {
Bar x, y, z;
(fgets()とかのコード)
} catch (Exception ex)
fclose(fp)
}
}
とかなコードを見たら普通の人は「chatchに飛んできて大丈夫なんか?」とtryブロック内をチェックするが
(x, y, zの解放が保証される、とかは関係無しに
例外安全主義者にかかってはそんなことはお構いなしである。とにかく安全と言い張る バカの主張: バグがあるかも知れないから例外安全は「使い物にならない」
アホすぎだろ… >>764
>例外安全はやれるならやった方が良いのは認める(>>721
>例外安全に予期せぬ事象が起きたときのセーフティーネット以上のことを気体できい(>>727
というわけで文盲に言われたくは無い
特定のケースにおいて、例外でエラー処理を安全に書けてその後のリカバリーもスムーズにいきますよ、
みたいな特定方面で有効なソリューションとして例外安全を勧めるのであれば問題無いのだが、
テキストファイルをfgets()で読むという絶対的に正しい事柄への批判に無理矢理つなげようとするから
話がおかしくなる >>763
x,y,zのデストラクタならcatchに飛んだ時に呼ばれることは保証されてるけど…?
例えばyのコンストラクタで例外飛んでもxは~Bar()呼んでzは呼ばないくらいコンパイラがやってくれるけど…?
そういうの忘れずやってくれるのがコンパイラだから任せようぜっていうのがRAIIなんだけど…?
まさかこんな事も知らずに例外安全がどうのと偉そうに論じてたの?嘘だろ? >>766
ま た 文 盲 か
>(x, y, zの解放が保証される、
と書いてあるわけだが?
しかしだからといっても普通の人はtryブロック内をチェックするだろ、という主張 >>768
初心者はおとなしく教科書の質問だけしてろよ
何かを知っているふりをするのをやめろ >>769
質問ですが例外安全の教科書として藻前は何を読んだことがあるのでぃすか? > 例外安全主義者にかかってはそんなことはお構いなしである。とにかく安全と言い張る
どこの主張を言ってるのか知らんけどどう見てもお前の方が「文盲」なわけだがw >>763
RAII を使わず明示的な catch でリソース解放しているコードを見て、一般的な C++ プログラマは「危険」だと見るのでは?
その例だと「fgets()とかのコード」内の return などで fp がリークする可能性があるわけで。 誰が「例外安全なら大丈夫」と言っているの?レス番は? いつになっても
do {
} while(0);
でbreakをgoto代わりに使うしかないのか >>763
めまいがするほどのひでえコード
やめてくれバカがうつる >>743
観ようとしなければ何も観えない
そんな簡単なことにも気付けない >>757
2GB以上じゃなくて良いけど
そこそこの大きさのファイルで
書き込んでcloseしてる途中に
電源OFFとかになったら例外どころじゃないんだが
最近のOSはちゃんとコンデンサ放電仕切るまでの間に書き込み終了するんだろうか >>760
サンフランシスコ地震で高速道路崩落←直後に「日本では起こり得ない」と言われた
インドネシアの津波で街が吹っ飛ぶ←直後に「日本では起こり得ない」と言われた
チェルノブイリで原発爆発←直後に「日本では起こり得ない」と言われた
武漢でコロナ感染者急増でパニック&パンデミック←直後に「日本では起こり得ない」と言われた
いつも否定したがる人はいるしそれを信じたがるひともいる ファイル編集中、Ctrl+Sを押下して保存しようとした瞬間に停電になったことがある
再起動後、ファイルは存在しているのに中身は\0で埋められていたよ >>778
・UPSぐらい付けろよ
・障害が心配なら多重化しとけ
って話で例外安全とはレイヤーの違う話 >>770
古典だけどExceptionalC++あたりから読み始めるのがいいよ
準拠規格が古いから所々アレだけど大きな考え方を学ぶには十分だろう
感想聞かせてね 786以降C++なコードもC++なURLも載せないやつは発言禁止な >>763
try内のコードが例外出さない限りcloseされない 確かにそうだ
すっかりfinallyのつもりで読んでた
やはりRAIIは正義 いーやfreadで2G超のファイルはvsでも完全にあつかえる不都合はない
と、自信を持って断言できないゴミが
URL乞食でドヤってるのバカすぎ fseek()/ftell()が32bit用でfseeki64()/ftelli64()の方を使ってないというオチか 自信をもって断言したところで、モリカケ・桜を見る会と同じことになるだけだよ
アベノセイダーズは不具合を見つけてくるまで決して許さない >>789
コストラクタでラムダ式をメンバ変数に受け取りデストラクタでそのラムダ式のメンバ変数を実行するクラステンプレートを自作すれば問題解決 不都合があるという主張であろうと
不都合がないという主張であろうと
自分でコード書けないゴミは引っ込んでろ 再帰呼び出し
我々の宇宙は高度な文明を持つ知的生命体の実験により作られたものであると推測するハーバード大学の科学者 : カラパイア
https://karapaia.com/archives/52306877.html >>796
おいURL乞食、おまえに言ってんだよ、おまえに
俺はftellで例示するコード出してんだよ
同類呼ばわりすんな穢らわしい #include <iostream>
#include <fstream>
#include <vector>
#include <cstdio>
#include <algorithm>
int main()
{
const char path[] = { "hoge.dat" };
std::vector<char> buffer(1024 * 1024); // 1MB
std::ofstream f(path, std::ios::binary);
for (int gb = 0; gb < 5; ++gb) {
std::fill(buffer.begin(), buffer.end(), static_cast<char>(gb));
for (int i = 0; i < 1024; ++i) f.write(buffer.data(), buffer.size());
}
f.close();
#pragma warning(suppress : 4996)
std::FILE* fp = std::fopen(path, "rb");
for (int i = 0; i < 5 * 1024; ++i) {
if (std::fread(buffer.data(), sizeof(buffer[0]), buffer.size(), fp) < buffer.size()) return 1;
for (auto ch : buffer) if (ch != static_cast<char>(i / 1024)) return 2;
}
std::fclose(fp);
std::cout << static_cast<int>(buffer[buffer.size() - 1]) << std::endl;
return 0;
}
とりあえずVC++2019でx86(32bit)ビルドして実行したら終了コード0の出力4だったのでfread 4GBは超えられてる模様 >>799
それは、おま環にすぎないので不具合がないことの証明にはならない
不具合を見つけるのがお前の責務だ
赤木さんのように自○したくなるまで頑張って探せ プログラム技術板の正規メンバに
クソ以外の乞食が何か寝言ぬかしとんな お前らの家の冷蔵庫にエルビス・プレスリーがいないからといって、この世にエルビス・プレスリーがいないことの証明にはならないんだよ
血を吐くまで探せ あぁ?わかって言ってんのか?
泥棒の証拠を泥棒に探させるのがアベガー品質だぞ 元々>>637がC++でもfgetsを使う俺は天才などとのたもうて
>>687がFILE*を使うなら例外安全をどう保証するのという話だったのが、
当の>>637は>>691でfread/fgets自体が例外を投げる可能性(?)という謎の問題を考え始め
>>710が根拠不明の2GB制限の話を持ち出し
問題があると考えるひとは存在しない2個の問題を同時に考えて混乱し
まあまあ分かってる人はRAIIすればいいじゃん(ってかfstreamでいいじゃん)で話が終わっている
まとめるとこんなところか? 挙証責任をガン無視できる文部科学省元事務次官前川喜平こそ最強
座右の銘は面従腹背、ライフワークは貧困調査 >>806
俺はcの標準ライブラリ使うならosの関数使えって言ってた人でアンカの中には登場しない人だけど
「根拠不明の2GB制限」についてはlarge file問題というのが昔あった
https://en.wikipedia.org/wiki/Large-file_support
LinuxなどUnix系が64bit環境にほぼ移行した現在その問題はレアケースだとは思うけど
32bitアプリが割と残っているWindowsだと実際のところどうなのか分からない
でもfreadくらいは出来そうだと考えわざわざコード書いただけ(>>799)
ちなみにLinuxでもdebian系のantiX 19.4 32bit環境では#define _FILE_OFFSET_BITS 64がないとfopenがNULLを返していた 話の肝は「私が間違ってました。ごめんなさい」と素直に言えるかどうかなわけで
小室文書みたいな屁理屈の羅列はいらねンだわ >>807
NHK は メード イン ジャパン とか オーダー メード とか表記するのに
メイド 喫茶は なぜ メイド 表記なのですか? ちなみに>>809の「cの標準ライブラリ使うならosの関数」という意味で以前実験した結果も貼っとく
read, fread, std::ifstream::readの比較
https://ideone.com/H2jc7B
systemdのユーザーごとのRAMディスクを使っているのでそれがある環境でだけ動作する
ubuntu 20.04 64bit環境で実行した結果だと↓
$ g++ -O2 test.cpp -o test
$ ./test
227
267
225
$ >>811
前者がmadeで後者がmaidだからじゃね? ババ抜きはOld maidの日本語訳だよ
セクシズムやエイジズムはポリコレの立場から見てどうだろうね >>812
その比較でなんで fread だけ遅いんだ?と思ってコード見たら fread じゃなくて fgets になってた。
あと read_cpp_standard() の if (std::cin.fail()) もたぶん f.fail() の間違い。 >>815
フェミが言葉狩りのネタにしないのは何故 >>818
thx
>>812のコードは脳内破棄してくれ
指摘された部分を修正した
https://ideone.com/DoI3ww
同環境での測定結果が↓
214
213
214
freadだとバッファリングされるからその分遅いのかと勝手に思ってたらそんなところから間違ってたとはすまんw freadのバイナリな
DMA効くのは
テキストはゴミ >>822
ジジ抜きもあるよ。
ジジ抜きはジョーカーを使わない。
適当な札を一枚抜いておいて組にならない札を最後まで持ってた奴が負け。
どれが負け札なのか最後までわからないというのがゲームの面白い部分。
ちなみに日本語でジジ抜きと呼ばれているゲームこそが Old maid (行き遅れ、お局様) の本来のルールで、
ペア (結婚相手) がないことを Old maid に喩えた命名になっている。 C++20ちょっと書き始めたらvscodeのインテリセンスが何でもないところにエラーの波線出しまくってくる >>828
OS: Windows 8.1 (64 bit)
コンパイラ: MinGW GCC 11.1.0
文句を言ってくる拡張機能は多分普通の"Microsoft C/C++ 拡張機能"でコードの例としては
https://wandbox.org/permlink/Fcqjvfqt8rWVqren
こんな感じ
エラーは
operator<=>: 戻り値の型だけで識別される関数はオーバーロードできません
requires(1個目): こちらでは requires 句は許可されていません (テンプレート関数ではありません)
vec: エイリアス テンプレート "vec" の引数リストがありません
v: ';' が必要です
という感じ
まあエイリアスのやつはC++17でも言えるけど Pythonのリストのように不定型の配列を作るにはどうすればいいですか?
vector<int> a;
vector<double> b;
vector<vector<any>> hoge;
hoge.emplace_back(a);
hoge.emplace_back(b);
みたいなことをしたいですが、エラーになりました。
最終目的は、
void f(vector<vector<any>>, vector<vector<any>>)
のような不定型配列を複数引数に取る関数を作りたいです。 >>830
出来るといえば出来るんだが、動的型っぽいことを C++ でやろうとすると煩雑だよ。
std::any は何でも格納できるが使うときには結局は元の型として取りださないといけない。
格納することが出来たとして、その後にどういう風に使うのかによってデザインの仕方がかわってくる。 >>832
うん、実用に供するまでには結構大変そう、使い道がわからん… >>834
クラスの設計段階で抽象クラスとの継承関係を作っておくだとかいった方法で多相にするのが
旧来からの方法で、それができるならそのほうがまともなものになると思うんだが、
そうは言ってもユーザーからは弄れない既存のクラスをどうしても使いたいということも無くはない。
根本的な部分をいじれないときに場当たり的にどうにかするよりは std::any や std::variant を使ったら
少しはマシかもねという程度の話で、あまり積極的に使うようなものではないというのが私の感触だな。 >>832
その後の使い方は、基本的には
全要素をany_castでstringにして使うつもりです。
不定型可変長のデータを受け取ってcsvファイル出力に使いたい感じです。 >>830
any使うんだったら、
vector<vector<any>> hoge;
じゃなくて
vector<any> hoge;
じゃない? >>835
>>833じゃないけど>>833のdump()を例えば
template<class... Args>
void dump(const std::variant<Args...>& e) {
std::visit([](const auto& x){
std::cout << " " << x << std::endl;
}, e);
}
template<class V>
void dump(const std::vector<V>& v) {
for (const auto& e: v) {
dump(e);
}
}
みたいにするんなら
class Dumpable {
virtual void dump() = 0;
};
みたいな抽象クラス作って素直にArgsの各classが継承(実装)した方がいいと思うってこと? >>840
そう。 クラスごとに違う挙動が必要ならその違いはクラスの中に隠蔽されているべきで、
クラスを使う側で分岐するのはなんかちょっとあれだなという感じ。
型を調べて分岐するようなコードが嫌だから動的な型を調べる機能を意図的に入れなかった話は D&E にも書かれてる。
(最終的には typeid が導入されてしまったけど……)
ただそれは「型を追加したくなったら分岐も増やすのはめんどいしミスしそう」みたいな話なので、
十分に賢いユーティリティが標準で用意されている今ならそれほど強い動機でもないんだけどね。 C++はパラメトリック多相が無いからこういうのは面倒だよね。
とりあえずはstd::vector<std::function<std::string()>>に[v](){ return std::to_string(v); };
あたりを入れとくのが簡単かね。
conceptを「その制約を持つクラスの総称クラス」としてshared_ptrあたりで指定できるようになると便利なんだけどなぁ。
concept_shared_ptrとか用意してくれんかね。 >>837
any_cast での取り出しは「元の型」でなければならず、
string に変換可能な型であっても any_cast<string> は出来ない。
(やったら例外が飛ぶ)
最終的に文字列になると決めているなら文字列にしてから格納したほうがすっきりするんじゃないの。 >>771-772
以下のような場合についてBarクラスがRAIIであるというだけでどう例外安全にできるのかお考えをお聞かせ願えますか
void foo() {
{ // 何かのコードブロック (try { } catch { } のtry{ } とかでも良い
Bar x, y, z;
(例外を生じる可能性があるコード)
アプリケーション固有の別スレッドXにイベントなりシグナルを送る
}
}
>>723
上に書いたようなケースを踏まえてっ例外安全に言及している>>720と>>721に対して
理解しいないまま捨て台詞を残して逃走した>>722とか、 >>772
コードブロック内のreturnがあるかもしれないんならチェックすれば良いやん?
>>763は普通の人ならチェックするでしょ、という主張
ところが>>722のような例外安全主義者ときては、RAII = 例外安全、で脳がショートしているのや
多分周りも能力に忖度して大した課題を与えていないんだと思う 上では例外安全にするとかしないとか言っていたような気がしたが少し主張が変わったのかな。
- 例外安全を求めるのは当然
- RAIIを使えば比較的例外安全を保証しやすい
- だからといってRAIIを使えば自動的に例外安全になるわけではない
結論としてはこんな感じだと思うが。 チェックして例外出さないと解放されないコード書いたのか… そりゃ例外安全もRAIIも魔法じゃないんだから使えば即安全になるというわけじゃないわな
「ちゃんと使えば」をすっ飛ばして>>845みたいなことを言い出すのも一種の思考停止だろうと思うわ >>845
Barのデストラクタの責務は自分が確保したリソースをリークしないことだけだ
オブジェクトの外側でやってるスレッド間通信のことなんかBarは知らんし別に手当するだけの話
逆に聞くがRAIIを嫌がってBar* x = new Bar;とかにしたらなんか事態改善すんの?スレッド間通信を簡潔に書くための役に立つの? そもそもRAIIが例外安全のためっていうイメージ全くないんだけど
リソースのお片付け(≒メモリリーク防止)が主目的ちゃうん? 例外が発生するとリソースを片付け損ねる場合があるってのが例外安全を欠く一番よくあるケースだと思うけど。
主目的がどうとかは別として。 >>845
例外を生じた場合でもXとなんらかの通信を行うべきなら
thread_connectionみたいなクラスを作ってデストラクタに整合性を保つためコードを書くのがいいかな
「アプリケーション固有の〜を送る」の部分にはそのオブジェクトのメソッド呼び出しにしておく
例外発生時にはデストラクタによってXスレッドに異常を通知してXスレッドが持つ状態の整合性を確保してもらう
Xに通知するのが単なる終了通知なら(成否を区別して処理しなくていいなら)全部デストラクタでいいかもね 例外でデストラクタ呼ばないケースなんてあるんですか?
プログラム自体が止まるのは別として これg++ 9.3だとstd::endlがなぜかconst variant<>と思われてエラーになってるみたいなんだけど、なぜ?
#include <variant>
#include <iostream>
using namespace std;
template<class C, class... Args>
C& operator<<(C& out, const variant<Args...>& v) {
visit([&](auto& x){out << x;}, v);
return out;
}
int main() {
cout << endl;
return 0;
}
https://godbolt.org/z/dbodW3xfG >>838
「「最初から void * な実体」は作らない」「void (*)(void *, ...) くらいまでがせいぜいだ」というように努めていた私は愛し方が足りなかったのでしょうか?
最近の愛し方:https://mevius.5ch.net/test/read.cgi/tech/1624028577/305 >>857
std::endl は関数テンプレートなので型と比較しようとするとインスタンス化に失敗するというエラーだと思う。
(std::endl を普通に使うときは左辺の型を利用して推論される。)
型を明示して渡せば variant との比較に失敗して通常の改行として解釈してくれる。
#include <variant>
#include <iostream>
using namespace std;
template<class C, class... Args>
C& operator<<(C& out, const variant<Args...>& v) {
visit([&](auto& x){out << x;}, v);
return out;
}
int main() {
cout << static_cast<std::ostream&(*)(std::ostream&)>(std::endl);
return 0;
} >>859
う〜ん、よく分かりませんね。確かに勝手にendlは[with _CharT = char; _Traits = std::char_traits<char>]なbasic_ostreamを
引数にとって返すと想定しちゃってましたが、その時点でインスタンス化しようとしてエラー出す理由が分からない・・・
例えばテンプレート引数を直指定しても
#include <variant>
#include <iostream>
using namespace std;
template<class C, class... Args>
C& operator<<(C& out, const variant<Args...>& v) {
visit([&](auto& x){out << x;}, v);
return out;
}
int main() {
cout << endl<char>; // ここが違う
return 0;
}
同様にエラーのままでした。castしたときだけなぜ判定失敗してくれるのかもう少し考えてみます。
ありがとうございました。 >>860
左辺が曖昧だからかもしれない。
左辺の型を std::ostream で固定すれば通る。
#include <variant>
#include <iostream>
using namespace std;
template<class C, class... Args>
std::ostream& operator<<(std::ostream& out, const variant<Args...>& v) {
visit([&](auto& x){out << x;}, v);
return out;
}
int main() {
cout << endl<char>;
return 0;
}
でもこのとき型変数 C は不要だなと思って class C を削るとエラーになるんだよな。
なんだかよくわかんないね。 >>861
度々ありがとうございます。再現確認したところ、確かに余計なテンプレート引数が1つあるだけでこのエラーが出ないみたいですね。
試しに元のコード(>>857)に余計なパラメータを1つ入れるだけでも通りました。
#include <variant>
#include <iostream>
using namespace std;
template<class T, class C, class... Args> // ダミーパラメータT追加
C& operator<<(C& out, const variant<Args...>& v) {
visit([&](auto& x){out << x;}, v);
return out;
}
int main() {
cout << endl;
return 0;
}
ほんとによく分かりませんね。
castの件は第2引数のvがテンプレート関数でなければ弾けるということのような気がします。
https://onlinegdb.com/ol3BYChIx 最後のコードは右上の設定ボタンから -std=c++17 を追加することで実行できます。 iostreamのシフト演算子オーバーロードは文句を言われてるがrangesのoperator|のオーバーロードはどうなんですかね 感覚的にはまあ順当だろうと思う。
日付やパスで / を使うのに比べればよっぽど……。 組み込みの意味を持たないオーバーロード専用演算子があれば良かったのにな
用意しておかなかったのはC++の初期デザインの失敗だったと思う 意味を持たない演算子が意図せず呼ばれてしまうくらいならコンパイルエラーになったほうがマシでは ところで Haskell で一定の記号の組み合わせは何でも新しい演算子として定義できる仕組みがある。
!#$%&*+./<=>? あたりとその他 Unicode 内いくらかも含めた組み合わせで演算子を作っていい。
優先順位も決められるし左結合か右結合かも決められる。
事実上無制限に違う字面の演算子を作れるんだよ。
<?+> とか #-. とか <<-~ みたいな演算子が実際に使われてるわけ。
こういう極端なのはさすがにあまりうらやましくはないよな……。
>>866
かといって有限の演算子をある程度に多く用意したところでオーバーロードを許すなら
どこかで全然違う意味で使われることもあるのは避けようがないし、
C++ くらいにスッパリと諦めるのもそれはそれで思い切りが良くて良いと思う。 演算子ってのはwellknownだからこそ意味があると思うんだけどな
演算子のオーバーロードもその“意味”から大きく逸脱しないことを求めていたと思うし
意味を持たないオーバーロード専用演算子ってのは
プログラマーによって意味が真逆になりかねないから危険だと思う
そんなことするぐらいなら普通に名前を付けて関数定義したほうがマシに思える そこら中訳わかんない記号だらけのソースとか悪夢でしかないなw >>866
リザーブの演算子持っとけって言いたいんだろうけどこう言う奴はいくつ持ってても足りねーとか言うからw 演算子オーバーロードって自分で書くにはいいけど他人のコードを読むのが地獄だな。 while (fread(&x, sizeof(double), 1, fin) > 0) {
fprintf(fout, "%5.4f\n", x);
}
こんな風に書くとコベリティ君がfreadは読み込んだバイト数を返すが使っていませんみたいなこと言い出すんだが
は?使ってますけど?みたいな気持ちしかないんだけど
何を求められてるんだろうか。 演算子に限らず、ある関数を特定の名前空間の内部だけ使えるように限定できたっけ?
「あるスコープだけこういう使い方」ならまだ混乱も少ないかね。 関数内で構造体を定義し、その中でstatic関数を定義する あ、違った
class内のprivate関数でいいんじゃね >>878
名前空間の外にお漏らししないようにできたっけ?
同じ名前空間にクラス定義しなければADLも気にしないでいいのかしらん。 niebloidの出番じゃないの?演算子オーバーロードには使えないが >>882
そうそう、そんな感じ。
実際には演算子を閉じ込めたい名前空間の中でクラスを定義しなければADLは影響しないけど、もし定義するとしてもこの技法で回避できそうだね。 std::function を引数にとる関数を作ってるんだが、参照で渡すのとコピーで渡すのでどのように動作が変わるかわからない
参照で渡して良いですか std::funcて中身は関数ポインタ―でしょ
コピーで済むものを参照で渡す必要はそもそもないんじゃないの
受け取り先で書き換えて返すなら別だけど >>888
「引数にとる」というのは実引数の型も std::function 型という意味? >>893
仮引数の側を std::function の参照にしたところで、実引数の側が std::function ではないときは
変換して一時オブジェクトを作ってからその参照をとる形になるんだよ。
これは std::function に限らない一般原則。
どちらにしても新しいオブジェクトを構築するので参照にする意味がない。 クラスのメンバーにstd::functionをいくつか用意しておいて、
条件によりどれかのstd::functionを引数に取るprivateなメンバ関数とかなら参照にする意味はあるかもしれないw この流れで質問をば。
std::functionだと単体のR opetator()(Arg...)しか指定できないけど、複数のメソッドを指定できるように拡張するにはどうしたらいいかしらん?
継承じゃなくてtype erasure を使ったgeneral smart pointerとでもいうようなやつが欲しいんだけど、どこかに実装ないかなぁ。 anyだとメソッドを呼び出せないから機能が足りないですな。
メソッド呼び出しできるインターフェイス付きanyみたいな感じ。
用途は「指定したメソッドがあれば継承関係無しでブチ込める親クラスみたいなanyみたいなshared_ptr」だけど。 理解できてないけど普通のテンプレート引数を持つ関数じゃいかんの? Haskellの型タイプというのがイメージに近いか。
具体例をだしてみると、
class A { public: string test1() { return string("A1"); }; string test2() { return string("A2"); }; };
class B { public: string test1() { return string("B1"); }; string test2() { return string("B2"); }; };
vector<generic_ptr<string test()>>c;
c.push_back(make_shared<A>());
c.push_back(make_shared<B>());
c[0]->test1(); // A1
c[1]->test1(); // B1
c[0]->test2(); // A2
c[1]->test2(); // B2
みたいに、anyみたいに雑多なオブジェクトをブチ込むけど、
anyとは違ってそのまま共通メソッドを呼び出せるようにする、
というのが狙いね。 >901
ありがとう。こういうのもあるのね
……でも BOOST_TYPE_ERASURE_MEMBER を使ったコンセプトがWandboxで上手く動かないなぁ。
もうちょっと試してみるか。 std::thread で作られるスレッドって
スタックサイズはデフォルトいくつなん?
変更とかできるん? >>903
スタックなんて概念がないのに制御できるわけがない linuxならulimit -sかpthread_attr_setstacksizeで設定できる
ただ確保されるのは仮想メモリなので現実的にはその設定あんまり使い所がない
そしてC++とか関係ない 意味わかんなくてpthread使ってんなら相当頭悪い 基底クラスに定数持たせるけど値は継承先で決めたい。
例)Carクラスには計算に使うが変更はしない定数 weight hight width があり、それは継承した車種クラス毎に異なる、など。
下記でコンパイル通るようですが、定数増えると見づらく、もっとスマートなやり方あったらご教授願いたく。
class Car
{
protected:
const double weight, height, width;
public:
Car(double w, double h, double wd)
: weight(w)
, height(h)
, width(wd)
{}
};
class CarA : public Car
{
CarA() : Car(1000.0, 1.8, 1,8) {}
}; 値が const であるだけでなく static であって欲しいという意図なんじゃないかと想像する。 クラステンプレート化すればいいじゃない
template<double W, double H, double WD> >>915
C++20 で非型テンプレート引数の大幅な緩和があった。 >>911
virtual double weight() const = 0;
じゃあかんの? >>912
引数が数値ばかりで10個とかあると確かに何を指定してるのかぱっと見わかんなくなりそう
C++なら>>918に一票だけど参照する時に ( ) が要るからこう言うケースだとC#のプロパティが欲しくなる >>911
Builderパターンとか?
面倒だったらDirectorクラスは省略しても問題なさそう。
類型的な車種ごとにBuilderを派生させてデフォルト値を決めといてもいいかと。 >>919
参照するときに()ていうのは
a=car.weight(); ていうこと?
a=car.weight; と表記したいならoperator=をオーバーロードすればいいかと >>920
C++20で使えるのそれそれ。gccでは元々使えるけど... >>923
C (C99 以降) には有るからついでに C++ でも使えるようにするのは gcc 的にはたいした手間でもなかったんだろうと思う。 ところで C の designated initializer では配列要素を指示することも出来るんだけど、 C++20 にはこれは入らなかったんだね。
↓ こういうの。
const char *foo[5] = {
[2]="bar"
}; c++17以前でも引数を構造体にまとめれば{}で区切って記述できるようになるから多少マシにはなるよね
IntelliSenseが効きにくくなるのが欠点だけど そのCの記述素晴らしいよね
C++的でないのはわかるがどうせ初期化時でしか使わんのだしとっとと入れるべきだった >>925 ラムダ式のキャプチャと競合するためと書いてるね https://ideone.com/d05dJ9
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
#define MAX_SIZE 100
template <class T>
// template <class T, size_t C=MAX_SIZE>
class SizeLimitedAllocator {
public:
typedef T value_type;
using traits = allocator_traits<allocator<T>>;
T *allocate(size_t n) {
if (n > MAX_SIZE) throw bad_alloc();
// if (n > C) throw bad_alloc();
return traits::allocate(_allocator, n);
}
void deallocate(T *p, size_t n) {
traits::deallocate(_allocator, p, n);
}
private:
allocator<T> _allocator;
};
int main()
{
vector<char,SizeLimitedAllocator<char>> vec(MAX_SIZE);
try { vec.resize(MAX_SIZE+1); }
catch (bad_alloc& e) { cerr << e.what() << endl; }
return 0;
}
このコードをコメント側に変更してコンパイルするとこけるんだけど、なんで? >>930
https://en.cppreference.com/w/cpp/named_req/Allocator#cite_note-2
> rebind is only optional (provided by std::allocator_traits) if this allocator is a template of the form SomeAllocator<T, Args>, where Args is zero or more additional template type parameters.
これですかね?
カスタムアロケータ自分で定義したことないのでじゃあどうすればいいかは分かりませんが…… >>930
SizeLimitedAllocatorの定義にこれ追加すればいいよ
template<typename U>
struct rebind {using other = SizeLimitedAllocator<U,C>;}; グーグルテストのASSERTの片辺に期待値をマジックナンバーじゃなくマクロ定数で指定すると赤線引いて来やがるんだけどVSだけ?
ビルドは通るしテストもできるから全く問題ないんだけどうぜー 大体のコンパイラはそういう#pragma持ってるだろ
MSVCなら#pragma warning
GCCなら#pragma GCC diagnostic 改行コードとかタブコードとかが含まれた文字列を
\nとか\tとかにエスケープしてくれる関数ってある? std::replaceは?
sjisだとまずいかも 文字コード周りはカオスすぎて標準も手に負えず匙投げたからライブラリ使った方がいいよ >>939
C/C++の場合、1文字単位での文字列処理が得意なので、自作するのも簡単。
0x09 や 0x0a は、SJISやUtf8などの多バイト文字の中には含まれて無いから、
なおさら。
例えば、std::stringでも、新しい文字列変数dstを作って、srcの文字列
から1バイト単位で読み取って、dstに1文字ずつ末尾追加していけばいい。 >>944
[具体例]
MFCのCStringなら、以下のようにするだけでよい:
CString src = "元の文字列";
CString dst; // 変換後の文字列を入れる変数。
const char *ptr = (const char *)src; // CString の 0 終端文字列の先頭アドレスを取得するための変換関数を呼び出している。
while ( *ptr != 0 ) {
if ( *ptr == 0x0a ) {
dst += "\\n";
}
else if ( *ptr == 0x09 ) {
dst += "\\t";
}
else {
dst += *ptr;
}
ptr++;
} >>945
[補足]
このプログラムは、1バイトずつ読み取っているが、文字符合は、このままでも、
無修正で ASCIIだけでなく、SJISやUTF8やEUCにも対応している。
後者のような符合では、例えば、SJISの"あ"の文字だと、1文字単位ではなく、
1バイトずつ処理され、2回ループが回るが、問題ない。
UTF8だと3回ループされる。
つまり、このプログラムでは、SJISの1文字は、2文字のように
UTF8の"あ"の文字は、3文字のように処理される。
しかし、それでも結果的には問題ない。
なぜなら、0x0aや0x09は、多バイト文字の中には含まれてないから。
ただし、SJISの場合、\ の文字コードが含まれているので注意が必要ではあるが、
今回は問題ない。 >>946
[補足2]
char は、C言語が登場した時には、「文字」の意味であったが、
今は少なくとも C言語では文字の意味はほぼなく、1バイト(8BIT)の意味である。
そして、C言語でcharが1バイト(8BIT)で無い処理系は、主流ではないので無視
してよい。
Javaなどでは、charが 必ず16BITであるのとは対照的である。
ただし、Javaもサロゲートペアの文字に対しては、charは文字の一部であって
本当の1文字には対応していない。
※結局、どの言語も、1文字を固定長で扱い続けることは避けている。 老害が一生懸命考えたんだろw
メモリリークしまくられるよりマシ CStringにせよbasic_stringにせよメモリ確保の多発なんて心配しなくていいよ
JavaのStringじゃないんだから こういう時reserveしてなくても問題ないの?
最大容量わかってるやん。 メモリ2倍取るのと再配置とどっちが無駄かはそれこそ環境と目的次第だろ >>945
CStringA
もしくは _T("\\t")他 vectorもそうだけど、倍々にメモリを再配置していくアルゴリズムがそこそこ効率的なので、
たいていの場合はreserveしようがしまいが有意な差は出ないよね >>943
ほんそれ
std::codecvt_utf8_utf16とか黒歴史でしかない プログラミングとしてはiso2020使ってた頃と大して変わらんよね
低レベルで吸収してくれんとやってられん ファイル読み取りもシステムコール側が独自にバッファリングしていることが多いから
プログラマ側ががんばってバッファリングしても二度手間だったりする >>955
utf32<->utf8
utf32<->utf16
で十分だと思っていますが
というか、 utf16 自体が黒歴史… >>958
stdio.h をディするのはそこまでだ 文字コードなんて事実上iconvが標準だろ
せいぜいicuくらい
他は一部のプラットフォーム固有の関数くらい
制御コードはISO2022でもなければ使わんし、いうてwhite spaceの類は使われてないから気にすんな
真面目にやると文字の境界見つけんのがだるいし、合成文字の扱いも微妙、異常系の仕様も要件次第になるし、Unicodeのバージョンも無限に上がりそうだけどなw
ってわけでC++とか関係ない話だからどうでもいいよ >>959
utf32<->utf8
utf32<->utf16
どちらも std:: のは黒歴史 >>959
結合文字列があるから、結局コードポイントに必ず1文字が対応しているとは限らないし、
何使ってもUnicodeは闇じゃないか。
まあ、UTF32使えばコードポイントがぶっ壊れることは避けられるけれども。 この場合同じコードポイントでの変換なわけだし一文字がどうとか関係ないが。 >>948
Perl/Ruby/JSなんかで正規表現を使って置換する場合でも、
同じようなアルゴリズムを使ってるはずだから、これが
特に非効率なわけではないし、代わりになるアルゴリズムで
これよりトータルで効率の良いものも恐らく存在しない。
1.例えば、0x0aと0x09の出現回数を最初に数えれば、必要な
dstのバイト数を見積もることは可能だが、その場合は、
二回もパースが必要になるし、プログラムも分かりにくくなる。
二回パースすることによる速度低下も有る。
2.dstのサイズはsrcのサイズの2倍を越えないので、単純に
dstの内部バッファをsrcのバイト数の2倍として予約しておけば
メモリ確保は一回で済むが、srcが巨大な時、メモリを圧迫し、
余り良いアルゴリズムとは言えない。 >>951
文字列のバッファは、不足すると2倍、2倍、・・・で確保されていくので
確保される回数は、最終的な文字列のバイト数を N としたとき、大体、
log2(N) 回程度となり、バッファがコピーされるトータルのバイト数は、
b = a + a*2 + a*2^2 + a* 2^3 + ... + a* 2^k
k = log2(N) 程度
a = 文字列クラスの内部バッファの初期バイト数。
となり、大体で言えば、2N を越えない。
1 + 2 + 2^2 + 2^3 + ... + 2^k
は 2進数で考えれば、全てのビットが 1 に成っている整数で、
2^{k+1} = 2*2^k = 2*2^{log2(N)} = 2 * N
であることに注意する。
ただし、bの値は大体で書いたので、厳密には少し違うだろう。 >>970
1 + 2 + 2^2 + 2^3 + ... + 2^k
= Σ_{i=0}^k 2^i
= (1 - 2^{k+1}) / (1 - 2)
= 2^{k+1} - 1
である。途中、等比数列の和の公式:
等比数列の和 = 初項 * ( 1 - 公比^項数) - ( 1 - 公比 )
を用いた。 >>971
誤: 等比数列の和 = 初項 * ( 1 - 公比^項数) - ( 1 - 公比 )
正: 等比数列の和 = 初項 * ( 1 - 公比^項数) / ( 1 - 公比 ) 俺は数年前業を煮やして自前のstringクラスを作ってしまった(´・ω・`)
・sjis/utf8/utf16/utf32対応で比較・代入などどの組み合わせでも問題なく動く
・どの文字コードでも同じハッシュ値を生成する
・char型がsjisなのかutf8なのかはdefineで決める
・テンプレートベースのformatを用意してprintfを置き換え
みたいな >>974
文字コードの種類に1バイト用意して、後はそれぞれの文字コードで直接保存している えー
コンストラクタで各種文字コードのバイト列を受け取れるようにして内部保持形式はUTF32でよくない? それだと大きめのテキストファイルを開いたときなどいちいち変換が入って遅くなりそうだから…といっても実際にはどっちが効率良いのかまでは比べてないけど
異なる文字コード同士比較する時なんかはコードポイント単位で読み出して結局utf32ベースで処理するしな… >dstのサイズはsrcのサイズの2倍を越えない
しね プログラマーは3種類しかいない
文字コードが分からない一般プログラマー
文字コードを理解したと勘違いしている地雷プログラマー
そして人類が文字コードを理解するのは不可能だと悟った上でなんとか事故が起こらないように心を砕く真の専門家だ >>976
あーあとは、これのstring_viewバージョンがあって、関数のパラメータをconst mystring_view& strみたいに受けると、どんな対応してる文字なら(リテラルや対応してるクラス含めて)なんでも参照として受け付けるから便利なんだよね 実質的にはほとんどなにも変わらないと思うけど、無駄なコピーが減る場合もあるので付けておくに越したことはないと思う まぁ、でも参照もコストゼロってわけじゃないから、場合によっては遅くなることもあるか… const って伝播するから嫌い
付けるのは反対ではないが 参照で受け取るときには const を付けないと右辺値を受け取れないんだよ。
&& にしたら逆に右辺値しか受け取れないし、
テンプレートにするのも面倒くさいし、
const 参照で不都合がないならまずそれを選ぶのが常道になってる。
積極的にそうする必要はなくても手癖でやるよね。 >>985
const 無しから const 付きの参照へは暗黙の型変換が許されるがその逆はない。
const 付きにしたらそれがずっと伝わっていくってことだ。
元のオブジェクトが const でないなら const_cast で const を剥がして書き換えるのは一応は有りなはずだが、
かなり行儀が悪いしな。 スコープ限定のconstを欲するひとがいるとは思わんかった 責任ベースのconstは有り得るのでは?
privateが在るんだから。 というか伝播しなかったら困るのでは?
お行儀悪くconst_castしない前提なら
ある関数の引数がconstだったら、その関数が呼び出す関数もまたconstであるという保証は大切だろうし もちろんそれは大切ですよ。
伝搬しなかったら意味ないし。 K&R2 にも const はありますが全然使わなかったなあ…volatile 同様キワモノだとおもっていました(爆) C++20からコルーチン入るけどコルーチンの返り値に関数内の変数の参照返すの問題になるかな?
hoge& test(){
hoge tmp;
for(int i=0;i<10;++i){
co_yield tmp;
}
}
//返り値は実際はgeneratorとかになるかもしれない 何かのリミッタが外れた感じだね
無差別にぶち込むようになった このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 98日 5時間 44分 33秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。