- 1 名前:デフォルトの名無しさん mailto:sage [2021/11/15(月) 18:49:18.44 ID:I69rZ/Of.net]
- 前スレ
C++相談室 part157 https://mevius.5ch.net/test/read.cgi/tech/1628474251/
- 562 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 02:08:50.44 ID:rFpP4pcL.net]
- しらそん
アウトプロセスサーバが生成する COMオブジェクトの中で異なるバージョンのCRTの混在が起きたら 同じことなんじゃないの なので
- 563 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 02:10:54.75 ID:P9feSsDc.net]
- 自演って見苦しいな
- 564 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 05:25:00.76 ID:0FjCQ3kx.net]
- >>549
そういうのをスマポでやれって話? ヘッダで提供されるライブラリだからスマポもダメだと思うんだけど
- 565 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 05:43:12.94 ID:a8PAglQ+.net]
- >>552
急にCOM持ち出すのはおかしいだろ >>553 ふつーCoTaskMemAllocじゃねえかな
- 566 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 07:28:31.98 ID:z66Mwoku.net]
- sin関数に入れる時間変数の値が大きくなるにつれ誤差が増えていって困ってます
fmod関数を使ってもあまり効果が見られませんでした 処理時間をそれほどかけずに解決出来る良い案何かありますか? sin関数に入れる値の目安は100万くらいです
- 567 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 09:18:24.17 ID:6eMF2SNy.net]
- 100万をsin()しても、sin()は2π周期
doubleの精度15桁中の5桁以上を無駄にしている sin()する用変数で毎回fmod(,2π)してもそこで誤差が貯まりそう boost::multiprecisionとか?
- 568 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 09:35:40.45 ID:/woV9P1D.net]
- 出来るなら入れる数を作る時点で[0,2pi)に収まるように工夫する
それが無理なら多倍長浮動小数点数のライブラリ使うか自作するか
- 569 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 10:28:27.14 ID:a8PAglQ+.net]
- >>559
sinの引数に入れる値を浮動小数点数で少しずつ足しこむような処理をしているなら、やめて別の方法を考えろ
- 570 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 11:32:37.05 ID:SV9DgXqP.net]
- sinに時間を入れるのは次元がおかしい
っていうのは冗談で、質問者が何を問うてるのかわからん sinにdoubleに収まるどんなデカい数を入れても精度は15桁くらい保証されるでしょ >>560 > 100万をsin()しても、sin()は2π周期 > doubleの精度15桁中の5桁以上を無駄にしている これもわけわかんねー 100万近いある数 x をsin()に入れるんでしょ? x も sin(x) も上から15桁全部有効な桁でしょ 何が無駄になってるん? >>562 こういう話ならわかる
- 571 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 12:03:23.64 ID:/woV9P1D.net]
- sinのテイラー展開にxの大きな累乗が現れるからだよ
100万をバンバン累乗した級数で値域[-1,1]の関数計算してたら誤差まみれになるのは直感的に分かるだろ
- 572 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 12:47:17.91 ID:6eMF2SNy.net]
- >>563
318310 * pi が100万に近い2piの倍数 https://keisan.casio.jp/calculator で、14桁で計算する 2 * pi = 6.2831853071796 sin(6.2831853071796) = 1.3523E-14 318310 * pi = 1000000.3575642 sin(1000000.3575642) = 3.291426496E-8 わかった? 桁数同じだから、でかい数は細かい所が消えるのよ
- 573 名前:デフォルトの名無しさん [2021/12/26(日) 15:05:31.07 ID:N3NYq5+A.net]
- わかんない。
- 574 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 15:55:33.50 ID:SV9DgXqP.net]
- >>565
現象としては確認できたが、理屈が分からない >>564の言ってるようにテイラー展開の各項が激しくキャンセルし合って桁落ちするってこと?
- 575 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 16:03:55.94 ID:6s7ujcJo.net]
- >>564
のテイラー展開は疑問なんだけど 関数が[0,pi/2.)への押し込みもやってくれるんじゃないの
- 576 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 17:28:50.32 ID:6eMF2SNy.net]
- 「桁数同じだから、でかい数は細かい所が消える」が理屈のつもりなんだけど…
sin(6.2831853) = -7.179586477E-9 だし、 sin(1000000.3575641670857) = -3.5E-14 だよ
- 577 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 17:52:52.66 ID:6eMF2SNy.net]
- sin()の結果に13桁の精度が欲しいなら、入力値に小数点以下13桁の精度が要るのよ
sin()は2piの周期関数だから 1000000の所に7桁も使っちゃうのはもったいないのよ
- 578 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 19:17:02.92 ID:P9feSsDc.net]
- まだ小学校の算数で分かる誤差の話してんの?
>>560で話終わらん奴は小学校からやり直せよ
- 579 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 19:41:54.46 ID:qnixUQRF.net]
- 桁に関する誤差とかどこの世界の小学校で習うんだよ
- 580 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 22:29:03.39 ID:Ep2AbKxF.net]
- お前は小学校の国語からやり直せw
>> まだ「小学校の算数で分かる」誤差の話してんの? 誰も小学校で習うなんて言ってないぞ
- 581 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 22:43:40.78 ID:RjefXsAR.net]
- log1pの存在理由も似たような話だね
- 582 名前:デフォルトの名無しさん mailto:sage [2021/12/26(日) 23:16:02.57 ID:P9feSsDc.net]
- 俺小学4年生で級数展開したπの計算してたけど・・・
6年生でアセンブラと実数使ってたけど・・・
- 583 名前:デフォルトの名無しさん mailto:sage [2021/12/27(月) 08:46:39.54 ID:B/I2o19O.net]
- 教える奴もよく分かってないからめちゃくちゃになってる
基本的には大きい数についても>>563の考え「x も sin(x) も上から15桁全部有効な桁」で合ってる sin() が 0 になるケースを考えてるからややこしいんだよ sin() が 1 になるケース、つまり pi/2 の奇数倍で 100 万に近い数を入れてみろ そしたらちゃんと 15 桁くらい 1 になるから 0 がややこしい理由は、仮数部が何であっても良いから 例えば 1e-20 は仮数部には1桁目からゴミが入っているが、倍精度ではゼロと見なす
- 584 名前:デフォルトの名無しさん mailto:sage [2021/12/27(月) 10:35:52.12 ID:wn+BpFxZ.net]
- >>576
お前は>>560様の爪の垢を煎じて飲んでから、小学校をやり直せ
- 585 名前:デフォルトの名無しさん mailto:sage [2021/12/27(月) 18:35:09.36 ID:osgcVgi4.net]
- uniform_real_distribution の範囲を可変にしたいときってどうしたら良いでしょうか
0 から 1 までの実数を生成するようにしてそれを変数変換するべきですか
- 586 名前:デフォルトの名無しさん mailto:sage [2021/12/27(月) 19:02:31.64 ID:DQqD3vMw.net]
- っparam
- 587 名前:デフォルトの名無しさん mailto:sage [2021/12/27(月) 20:26:27.31 ID:7ufKNB24.net]
- >>576
1になるケースでほぼ1になるのは、そこでの微分が0だからだよ 入力値がちょっとずれても結果への影響が小さいのよ
- 588 名前:デフォルトの名無しさん mailto:sage [2021/12/27(月) 20:45:16.64 ID:7ufKNB24.net]
- 「x も上から15桁全部有効な桁」だからこそ、
1000000の所に7桁も使っちゃうのはもったいないのよ sin(x)=0の所は微分が1または-1、入力のずれがそのまま出力に出る所
- 589 名前:デフォルトの名無しさん mailto:sage [2021/12/28(火) 01:04:16.62 ID:OVEU2JJm.net]
- 厳密な2πnと、doubleで表した有効桁数15桁の大体2πnに近い数字の差を計算すると、nが大きくなるほど差がデカくなってくるってだけの話じゃないの?
浮動小数点数は0から離れれば離れるほど目盛りが大きくなっていくのだから。 sinの実装がマクローリン級数展開でなくても起こる問題だと思うが。
- 590 名前:デフォルトの名無しさん mailto:sage [2021/12/28(火) 01:43:08.31 ID:NIM0c1vY.net]
- 小学生多すぎじゃないか?
- 591 名前:デフォルトの名無しさん mailto:sage [2021/12/28(火) 09:17:10.46 ID:p+qHklGW.net]
- おまえさん1人だろ
中学以後、いつ何を習うか知らないようだが
- 592 名前:デフォルトの名無しさん mailto:sage [2021/12/29(水) 21:49:37.03 ID:+eZ32Uo6.net]
- >1e-20 は仮数部には1桁目からゴミが入っているが、倍精度ではゼロと見なす
mjk、 IEEE754の2進数形式の倍精度浮動小数点表示は 仮数部がケチ表現の52 bit(実質53 bit)で 指数部は-1022〜+1023なのやぞ 1e-20とか1×2^(-60)かそこらなので無問題で53 bit(=15.9桁)の精度ェ、
- 593 名前:デフォルトの名無しさん mailto:sage [2021/12/29(水) 21:55:43.45 ID:+eZ32Uo6.net]
- >sin(x)=0の所は微分が1または-1、入力のずれがそのまま出力に出る所
x << 1のとき sin(x) ≒ x であることの見事な工学的応用、
- 594 名前:デフォルトの名無しさん mailto:sage [2021/12/29(水) 21:57:34.77 ID:+eZ32Uo6.net]
- まつがえた |x| << 1 やったorz
- 595 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 01:48:03.91 ID:L6Vpkxay.net]
- よっしゃ、よっしゃ、おっちゃんがいいもん作ったろう
https://ideone.com/fjxKtS n=0,10000, 20000, 30000, ...,1000000 (とりあえず10000刻み)として、 2分探索でsin(x)=0となるxを、2π*n付近について調べてやった そうやって求めたxをM_PIで割った結果はきっちり2*nになるから sin(x)がxの周期関数だからといって必ずしもxの増大につれ誤差が増えるわけではないことがワカル sin_valの値(=sin(x))が0に対して増えたり減ったりするのはマクローリン展開の近似多項式の係数を 結果があたりさわりのない誤差範囲でうろうろするように調整してあるんだろJK、
- 596 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 01:51:27.40 ID:L6Vpkxay.net]
- やっぱ>>562というものが>>559の誤差の真相なのではな
いか
- 597 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 02:32:05.49 ID:7UdZ08Kf.net]
- >>588
結果見たけど、sin_valの値は、きっちり0から10000になったときに5桁精度悪化してるし、100000で6桁精度悪化してるのでは…?
- 598 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 07:31:31.40 ID:xtSEOuqd.net]
- >>589
パッと見だけど>>565が答えじゃねえの 浮動小数点てのは文字通り小数点位置が異なる 数値が1付近と100万付近じゃ精度が異なるのは当たり前 精度を保つなら固定小数点使わないと
- 599 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 11:37:53.79 ID:ZhVAaRAF.net]
- まだやってたのか小学生・・・ID変えてご苦労様
- 600 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 11:39:17.39 ID:ZhVAaRAF.net]
- 何度も言ってるが>>560でこの話は終了している
- 601 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 12:38:33.70 ID:A3EHubzP.net]
- 質問主が現れないからもう何議論しても無駄な気がする
ソースコードがあるわけでもないし 100万程度で誤差ヤバい言うぐらいだからfloatで計算してないか疑たくもなる
- 602 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 14:43:33.58 ID:Wt/MKF34.net]
- 誰も計算機上のゼロについて理解できてない
- 603 名前:デフォルトの名無しさん mailto:sage [2021/12/30(木) 16:49:59.36 ID:uaiyfMI5.net]
- もまいら、浮動小数点のゼロ判定どうしてる?
- 604 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 00:22:01.38 ID:kcosmPcn.net]
- vectorでクラスへのポインタを持ってて、それを参照で受け取る関数を作るとき、クラスの変更を禁止したいんですが、どうすればいいですか?
例えば、 struct testclass{ int member; }; というクラスがあって、 vector<testclass*> を参照渡しで受け取る関数を作るとき、引数をconst vector<testclass*>& vecとしてもvec[0]->member =0みたいなクラスのメンバ変数の変更は関数の中で出来てしまうと思うのですが、そういうのをできないようにしたいです(testclassの変更が無いことを関数宣言で保証したいです) 何か良い方法ありますか? vectorが1重であればtestclass const*const*を引数にすればいいとは思うのですが、vector<vector<testclass*>>のように多重vectorみたいな場合も作りたくて、そのときは関数を呼ぶ側で多重vectorから多重配列に変換するのは面倒なので、できればvectorではなく配列を使うというのはしたくないです
- 605 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 00:36:47.69 ID:ysmsTKqS.net]
- >>597
禁止しない もしくはメンバ変数を非publicにしてgetter/setter
- 606 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 05:02:18.38 ID:zF3P5q1E.net]
- だから絶対値が1e-14とかより小さいかどうかだって
>>585なんかは全く理解してないようだが
- 607 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 05:10:34.66 ID:zF3P5q1E.net]
- ちなみにsinがゼロのとこは微分が1か-1でsinが1のとこは微分がゼロだから違うってのは、事実だが今回の事象の説明としては感覚的に過ぎるね
なぜならf(x) = xなる関数は微分は1だが f(1000000.3575642) は14桁正しいw sinの挙動について理解したいなら実装に踏み込むしかないよ あるいは>>576あたりで思考停止しとくか
- 608 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 06:37:46.15 ID:qJZ2APUI.net]
- >>597
アクセスを厳密に禁止したいなら、配列操作のみ定義したラッパークラスを用意して渡したほうが良い。
- 609 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 08:06:29.68 ID:FnYy2lty.net]
- んだね
- 610 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 08:45:47.76 ID:FPee+d5o.net]
- クラス T のメンバ関数で自身のコピーを返す(つまり返り値の型が T)ものを考える
メンバ関数の修飾が && のときは std::move(*this) とかしたいけどこれはいちいち書かないとダメ? 普通は std::forward で統一できるが
- 611 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 09:05:22.16 ID:FnYy2lty.net]
- *thisはxvalueではないからムブコンに渡したければstd::move()か(T&&)がいるね
- 612 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 11:52:30.35 ID:kcosmPcn.net]
- >>598
ありがとうございます ただ、 >メンバ変数を非publicにしてgetter/setter これだと結局setterでメンバ変数を変更できてしまいますよね? >>601 ありがとうございます、検討してみます
- 613 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 14:47:55.66 ID:fEOKhR13.net]
- instance.field; が暗黙のうちに書き変わらないだけでも効果あるんだよ
void f(T&t){ t.clear();} f(instance.field); うっかりこんなことしたらヤバいし const T& get_field() const; を使っとけばコンパイル時エラーにしてくれる >>597 冒頭の質問なら、参照渡し引数に void f(const T&); のようにconstつけとけばいい
- 614 名前:デフォルトの名無しさん mailto:sage [2021/12/31(金) 15:16:00.18 ID:7kXupeFa.net]
- >>597
まだ標準に入ってないけど、propagate_const使うとか https://ideone.com/O8a0hn
- 615 名前:デフォルトの名無しさん [2022/01/04(火) 07:21:58.04 ID:5hvio7Nh.net]
- Packtpubが不安定になってるんだけど。
見れますか?
- 616 名前:デフォルトの名無しさん mailto:sage [2022/01/05(水) 21:49:37.99 ID:2R8vvmqQ.net]
- クラステンプレートについて、明示的実体化しておけば実装を.cppでもできるというのを知ったのですが、その場合、テンプレートでない普通のクラスと同じように
部分的にヘッダに実装を書いて、残りを.cppに書く、というのは正式な書き方として許されるでしょうか?
- 617 名前:デフォルトの名無しさん mailto:sage [2022/01/05(水) 22:24:10.67 ID:tiBxT68+.net]
- 許される。
- 618 名前:デフォルトの名無しさん mailto:sage [2022/01/05(水) 22:48:02.56 ID:2R8vvmqQ.net]
- >>610
ありがとうございます!
- 619 名前:デフォルトの名無しさん mailto:sage [2022/01/06(木) 15:12:35.27 ID:C9LB+2SX.net]
- その昔、exportテンプレートというのがあってだな
- 620 名前:デフォルトの名無しさん mailto:sage [2022/01/07(金) 00:07:55.52 ID:UgPywUlD.net]
- class T;
class C { public: T t; }; とあったとき C c{T()}; と集成体初期化を行うと T のコンストラクタが1回だけ呼ばれます メンバ t をカプセル化してコンストラクタを自分で用意するとどうやっても T のムーヴコンストラクタが余計に1回呼ばれてしまうと思ったのですが回避する方法はありますか?
- 621 名前:デフォルトの名無しさん mailto:sage [2022/01/07(金) 02:01:17.79 ID:uUhimsKL.net]
- >>613
直接的にはないけど optionalとかvariantにあるin_placeコンストラクタと同じことをすればTのコンストラクタ呼び出しは一回で済みそう
- 622 名前:デフォルトの名無しさん mailto:sage [2022/01/07(金) 20:51:50.26 ID:UgPywUlD.net]
- >>614
ありがとうございます!
- 623 名前:デフォルトの名無しさん mailto:sage [2022/01/09(日) 10:55:01.80 ID:7BGFeByJ.net]
- >>597
配列の定義を vector<const testclass*> にすればよくない?
- 624 名前:デフォルトの名無しさん mailto:sage [2022/01/09(日) 11:30:20.08 ID:BcvcYHng.net]
- 外では変更するけど関数内では変更しないことを明示したいんでしょ
- 625 名前:デフォルトの名無しさん mailto:sage [2022/01/12(水) 09:32:50.44 ID:kvnPCGqB.net]
- 関数の定義で
auto foo() -> void{} みたいに書くの見かけたけどこのやり方何かメリットありますか?
- 626 名前:デフォルトの名無しさん mailto:sage [2022/01/12(水) 12:16:01.64 ID:SK9+pElf.net]
- あるね
auto s = std::string{"test"}; みたいな宣言とかも
- 627 名前:デフォルトの名無しさん [2022/01/12(水) 12:26:17.78 ID:Z0p/7uhd.net]
- >>618は型推論効いてないやん
- 628 名前:デフォルトの名無しさん mailto:sage [2022/01/12(水) 12:28:40.33 ID:VUzGdiiG.net]
- 戻り値の型を->の先に書いてあるだけだよ。
だからこれはvoid型の戻り値ね。 利点は引数からdecltype使って戻り値の型を指定できるくらいじゃない?
- 629 名前:デフォルトの名無しさん mailto:sage [2022/01/12(水) 13:45:01.07 ID:uq5/9jO3.net]
- https://www.fluentcpp.com/2018/09/28/auto-stick-changing-style/
この記事で論じられているね
- 630 名前:はちみつ餃子 mailto:sage [2022/01/12(水) 13:59:43.98 ID:7Sv8jpqL.net]
- ラムダ式で返却値の型をどう書くかというのが後置スタイルを導入した直接の動機だと思う。
普通の関数で後置にするメリットがない場合であっても、 メリットがある場合とない場合で区別して使い分けるよりは全部を後置で一貫させたほうが綺麗だと思うこともあるだろ。
- 631 名前:デフォルトの名無しさん [2022/01/12(水) 17:10:39.04 ID:VRtGvzgV.net]
- みずほが復旧をあきらめるとかどうみてもfukkyu
- 632 名前:デフォルトの名無しさん mailto:sage [2022/01/12(水) 18:43:03.08 ID:NICGWYWs.net]
- 人がつくったものネットから持ってきて何個も組み合わせて合体させるとみずほみたいになるんだろうな
自分で作ってない部分はメンテしようがないからな
- 633 名前:デフォルトの名無しさん [2022/01/12(水) 19:53:35.19 ID:UH3nST5b.net]
- Windows serverにしたのが最大の間違い。
- 634 名前:デフォルトの名無しさん mailto:sage [2022/01/12(水) 20:51:55.49 ID:VUzGdiiG.net]
- std::stringの大文字を全て小文字に変換するのってstd::transformより良いものあるの?
- 635 名前:デフォルトの名無しさん [2022/01/12(水) 22:50:55.12 ID:VRtGvzgV.net]
- Windowsで文字列中の大文字を小文字に変換する_mbslwr()って今やランタイムで使えなくなってんだね、知らんかったわ
- 636 名前:蟻人間 mailto:sage [2022/01/12(水) 23:14:22.56 ID:htST1fFk.net]
- CharLower
CharLowerBuff
- 637 名前:デフォルトの名無しさん mailto:sage [2022/01/13(木) 21:50:13.52 ID:bN4t5i1e.net]
- c++のexe → ライブラリA(c++のdll)
と c++のcリンケージのdll → ライブラリA(c++のdll) で 同じライブラリの同じ関数を呼び出してるのに 呼び出し元の形態によって挙動が変わるなんてこと有り得ますか?
- 638 名前:デフォルトの名無しさん mailto:sage [2022/01/13(木) 22:14:06.74 ID:+PFReeTS.net]
- ライブラリも呼び出し元も外部の同名のdllをリンクしているけれども
呼び出し元が参照しているdllの実体が別だったとか。
- 639 名前:デフォルトの名無しさん mailto:sage [2022/01/14(金) 09:16:33.28 ID:ovvIshUS.net]
- struct Vector2 { float x, y; };のような64bitで済んでしまうものの計算にSSE命令を使っても高速化は見込めないのでしょうか?
上記に対して_mm_mul_psを行うと上位2float分を余計に計算させることになってしまいますよね
- 640 名前:デフォルトの名無しさん mailto:sage [2022/01/15(土) 05:56:06.60 ID:ps658RNN.net]
- >>603
deducing thisがC++23で入るね
- 641 名前:デフォルトの名無しさん mailto:sage [2022/01/15(土) 16:29:52.27 ID:fx8S/FAM.net]
- >>632
余計に計算させるけど一命令で済むよ ただし速度以外のデメリット出てくるけど
- 642 名前:デフォルトの名無しさん mailto:sage [2022/01/16(日) 12:31:04.34 ID:20f7Ghpo.net]
- >>630
同じ関数というのが関数名と引数の数が同じというだけなら extern "C" double sqrt(double x); extern float sqrt(float x); とから有り得る
- 643 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 15:18:31.08 ID:sD13NBSV.net]
- pair<int, int> の first と second に、例えば座標と向きのような意味をもたせてるとします
このとき、using なんかを使って pair<int, int> x の第一要素と第二要素に x.pos、x.dir のようにアクセスする方法ってありますか?
- 644 名前:はちみつ餃子 mailto:sage [2022/01/17(月) 15:34:47.07 ID:jU2WrI4n.net]
- >>636
C++ ではメンバ (のように見えるもの) を後から生やすことは出来ない。
- 645 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 16:04:32.58 ID:+6BKuldY.net]
- auto& [x, y] = obj;
x = 100; y = 100; 動くかは試してない
- 646 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 16:07:55.78 ID:h5bglXe3.net]
- >>636
そういうあちこちで使う用途の、はっきり意味が決まった構造体は pairやtupleに頼らない方が(大抵の場面では)便利だよ その一箇所でしか使わないならpairでいいと思うけど
- 647 名前:はちみつ餃子 mailto:sage [2022/01/17(月) 16:18:00.13 ID:jU2WrI4n.net]
- いくつかの要件を満たして "Tuple-like" であるようなクラスはタプルのように扱える仕組みがある。
タプルを多用途に使うよりは個別のクラスを作った上でタプルのインターフェイスを持たせるほうが 使いやすくなると思う。
- 648 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 16:55:14.33 ID:aOF99LGB.net]
- >>636
まず構造体を勉強しよう
- 649 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 17:09:52.53 ID:bBHBfELI.net]
- struct だと困るんですか?
- 650 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 17:35:43.45 ID:AdXHrviP.net]
- みなさん御機嫌よう
このスレには何度も助けられているものです 再度お知恵を拝借したいです 任意のユーザー定義型のインスタンスhogeが、基底クラスbaseを継承しているか調べたいです。 この一例のみならtypeidで合致させればいいと思うのですが、実際は派生クラスが200くらいある予定です。 type-traitでインクルード出来るstd::is_base_ofで、RTTIを使い判定しようとしたのですが、typeidで取得できる型で合致させようとしたところ型情報が合いません……orz どんな方法でもいいので何かいい方法がございましたらご教授いただければと思います。 class base{}; class driv:public base{}; class foo{}; //もしhogeがfoo型のインスタンスなら偽を、drivのインスタンスなら真を返したい関数 bool exHantei(){}
- 651 名前:はちみつ餃子 mailto:sage [2022/01/17(月) 17:43:03.78 ID:jU2WrI4n.net]
- 老眼なので Hantei が Hentai に見えた。
- 652 名前:はちみつ餃子 mailto:sage [2022/01/17(月) 17:49:59.30 ID:jU2WrI4n.net]
- >>643
静的な型を判定するならこういうのでいけると思うが、 RTTI が出てくるってことは状況が違うのかな? #include <iostream> #include <type_traits> class base{}; class driv : public base{}; class foo{}; template<class T> bool exHantei(const T&){ return std::is_base_of<base, T>::value; } int main(void) { driv hoge; foo huga; std::cout << exHantei(hoge) << std::endl; std::cout << exHantei(huga) << std::endl; }
- 653 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 20:3
]
- [ここ壊れてます]
- 654 名前:6:31.89 ID:PMmhhAT1.net mailto: dynamic_cast<base*>(hoge)がnullptrかどうかを見ろ []
- [ここ壊れてます]
- 655 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 20:47:22.64 ID:6BYLlYWJ.net]
- >>643
bool exHentai(){ return std::is_base_of_v<base, std::remove_reference_t<decltype(hoge)>>; }
- 656 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 20:49:09.31 ID:AdXHrviP.net]
- >>645
ありがとうございます。 ただ今これで動作確認はしました。 が本来は基底クラスのポインタに格納されているのです…… 書き込む時に蛇足と思って省いてしまったのですが、実際は class base{}; class driv:public base{}; class WantToFind:public driv{} std::vector<base*> VecBasePtr; void pusbak() { WantToFind f1; VecBasePtr.push_back(&f1); } というようにベースポインタに押し込んで使っていて、exHantei()を使用する時にはベースとこのポインタを比較することになります。 今はちみつ餃子様のコードで動作確認をした後、自分のコード用に書き直したところ、ポインタから型を取得させる動作ができません(泣) てっきりtypeidと同じ様に、exHantei(*VecBasePtr[0]);と*を付けてポインタの中身を外に出せば生のWantToFind型が出てくるかと思ったのですが…… 思い通りの動作が出来ませんでした。 どうしてなんですかね、、、 デバッグモードで確認してもわからない もちろんbaseに仮想関数は置いてあるので、RTTIで動作してくれるものと思っていましたが。 Templateの機序が違うのかな……?
- 657 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 21:03:17.46 ID:PMmhhAT1.net]
- だからdynamic_castで調べろって
そのための機能だから
- 658 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 21:36:21.92 ID:AdXHrviP.net]
- >>649
ありがとうございます!!! 確認しましたところ自分の思っている動作が得られました☆*:.。. o(≧▽≦)o .。.:*☆ こんなに簡単に出来るとは、is_base_ofの使い所さんはどうなってしまうんだ。。。 レスへの返信を書きながら、自分でもコード確認やリファレンスを検索していたため、スレの確認が遅くなってしまい、多くの型と行き違いになってまいました。 返信をくださった方々には重ね重ねお礼申し上
- 659 名前:げます。
まだまだ弱輩者ですが、これからも生暖かい目で返信くださると幸いです。 皆さんありがとうございます! [] - [ここ壊れてます]
- 660 名前:はちみつ餃子 mailto:sage [2022/01/17(月) 21:36:54.84 ID:jU2WrI4n.net]
- >>648
動的型で継承関係を確かめるなら >>646 が述べている通り dynamic_cast で実際に変換してみるのは手っ取り早い方法だと思う。 > 生のWantToFind型が出てくるかと思ったのですが…… 「生の」ってなんやねん。 その場合の *VecBasePtr[0] の静的型はあくまで base だよ。 オブジェクトの base である部分 (サブオブジェクト) が取り出される。 いわゆるスライシング。
- 661 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 21:37:50.95 ID:AdXHrviP.net]
- dynamic_castは知ってたはずなのに思い出さなかったというか思いつかなかった……
- 662 名前:デフォルトの名無しさん mailto:sage [2022/01/17(月) 21:46:56.12 ID:AdXHrviP.net]
- >>651
ありがとうございます。 自分はスライシングもちゃんと理解してないですね…… ポインタのメモリ確保サイズが一様に8バイト(4バイト)なので、基底型が派生型の型を丸ごと格納している(派生型のポインタを確保している)と理解していました。。。(*を付けると派生型が出てくる) 悪魔でも基底型なのですね? キャストで受けるまでは基底型として扱われるので、型情報が合致しなかったのかな。 type_infoは、全く別の型を型合致に使うから*baseが有効なのかな。
|

|