1 名前:sage [2025/04/26(土) 10:34:58.41 ID:pbPDl6lv0.net] !extend:checked:vvvvv:1000:512 !extend:checked:vvvvv:1000:512 ↑同じ内容を3行貼り付けること 次スレは>>980 が立てること 無理なら細かく安価指定 ※前スレ C++相談室 part165 https://mevius.5ch.net/test/read.cgi/tech/1698705458/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
579 名前:はちみつ餃子 mailto:sage [2025/08/22(金) 10:34:20.59 ID:s1oN92u00.net] Python でも返却値として複数の値を返すことは出来ない。 Python で return にカンマ区切りで複数の式を書くとタプルになってる。 受け取る側で複数の変数を書いておけばタプルが分配 (unpack) されたりはするけど…… 関数が返却しているのはあくまでもひとつの値という理屈。 複数の値 (いわゆる多値) を関数が返せる言語はそれほど多くない。 LISP 系は多値のサポートがあることが多いけどそれ以外だと Go くらいじゃないかな? (マイナー言語だとわからんけどよく知られている主要な言語にはほとんどないと思う。) シンタクス的には C++ で return にカンマ区切りで複数の値を渡そうとしたとき、 つまり return 1, 2, 3; というように書いたときのカンマはカンマ演算子として解釈される。 カンマ演算子は左辺の結果を捨てる (評価はする) ので 3 だけが返却値になる。 C++ で複数の値をひとまとめにするには波括弧で囲む記法があって std::tuple<int, int, int> foo(void) { return {1, 2, 3}; } というように書けるんだが…… この波括弧は初期化の記法であってタプルのリテラルというわけではないのでそこんところは注意。
580 名前:デフォルトの名無しさん mailto:sage [2025/08/22(金) 10:49:05.94 ID:hiXhYkKD0.net] >>579 受け取る方はどうやって受ければいいのですか? 私の頭だと構造体で返せばいいかな なんつて
581 名前:デフォルトの名無しさん mailto:sage [2025/08/22(金) 11:06:34.54 ID:HM+/3rtsM.net] >>580 構造化束縛で取り出すのが楽 構造体を定義する手間が気にならないならそれでもいい
582 名前:デフォルトの名無しさん mailto:sage [2025/08/22(金) 11:49:05.11 ID:ZeYv0pFNd.net] C++も昔に比べれば随分と楽になった
583 名前:はちみつ餃子 mailto:sage [2025/08/22(金) 12:07:46.82 ID:s1oN92u00.net] >>580 タプルは単にタプル型の値なので普通に受け取れる。 auto bar = foo(); といったように書ける。 タプルから要素を取り出すのは std::get<0>(bar); といった要領になる。 受け取るときに変数に分配するやり方もあって atuo [r1, r2, r3] = foo(); というようにも書ける。 これを構造化束縛という。 おそらくこれが期待していたものなんじゃないか? この記法はタプルに限らずタプルライクな型、配列型、データメンバが全て公開直接メンバであるような型などであれば使える。
584 名前:はちみつ餃子 mailto:sage [2025/08/22(金) 12:23:44.06 ID:s1oN92u00.net] もし使っているコンパイラが MSVC なら MSVC のデフォルトでは C++14 になってるはずだからそのままだと構造化束縛を使えないかも。 (構造化束縛は C++17 から。) 私は MSVC を利用していないから具体的なやり方は知らんけど必要なら適当に設定してね。
585 名前:デフォルトの名無しさん mailto:sage [2025/08/22(金) 17:49:52.20 ID:hiXhYkKD0.net] どもです。構造化束縛ね。なんか聞いた事あるかなという程度だった。 使うかなぁ・・・
586 名前:デフォルトの名無しさん mailto:sage [2025/08/22(金) 21:41:35.66 ID:NcnZjMQ+0.net] 構造体ほど強いまとまりではなく、返り値だけのゆるいまとまりなら構造化束縛の方が便利だけどねぇ
587 名前:デフォルトの名無しさん [2025/08/22(金) 21:41:55.58 ID:iDw/vpGA0.net] >>579 std::tuple<int, float, long> foo(void) { return {1, 2.1, 99}; } atuo [r1, r2, r3] = foo(); って書いたら、 r1に1が、r2に2.1が入るの? まあそれでもいいかな PythonからC++に移植中で、ちょっと読みづらいと思ったので…
588 名前:デフォルトの名無しさん [2025/08/22(金) 21:45:40.16 ID:iDw/vpGA0.net] >>587 まあでも、なんで複数returnにしないのかね? outの引数が多すぎだわ
589 名前:デフォルトの名無しさん mailto:sage [2025/08/22(金) 22:11:20.77 ID:NcnZjMQ+0.net] Python でも複数return ってできないと思うけど? カンマ演算子でタプルを作って返してるだけでしょ
590 名前:デフォルトの名無しさん mailto:sage [2025/08/22(金) 23:03:10.61 ID:5NhjtIih0.net] そうやね。Pytnonのカンマは、言語仕様上は演算子とは一応区別されているみたいだけど、感覚的には演算子だよね。何で演算子ではないんだろうというのはちょっとした疑問だけど(1, みたいなのを後置演算子と呼ぶのはちょっと変とかそういうことかな?)
591 名前:デフォルトの名無しさん mailto:sage [2025/08/23(土) 01:30:59.35 ID:ynkOCuVA0.net] //こんな感じ? #include <iostream> #include <tuple> using namespace std; tuple<int, float, long> foo() { return {1, 2.1, 99}; } int main(){ auto [r1, r2, r3] = foo(); cout<<r1<<endl; cout<<r2<<endl; cout<<r3<<endl; return 0; }
592 名前:デフォルトの名無しさん mailto:sage [2025/08/23(土) 01:57:32.43 ID:HIKpDy1T0.net] 構造化束縛を調べてみたら fooの返り値はtupleでなくてもpairで返しても良さそうなんだけど どういうルールなの? キモい
593 名前:はちみつ餃子 mailto:sage [2025/08/23(土) 02:11:02.56 ID:CHT0FIec0.net] >>592 それがタプルライクの概念。 std::tuple_size の特殊化など、いくつかのインターフェイスを実装すればタプルと同じように扱ってくれる仕組み。 それとは別に配列の場合とか、全てのデータメンバが公開直接メンバなクラスもありということになってるのは単純に箇条書きで数種類のパターンを示す形になってる。 それほどパターンが多くはないがひとつの原則で表せるわけでもない。
594 名前:デフォルトの名無しさん mailto:sage [2025/08/23(土) 02:22:04.99 ID:HIKpDy1T0.net] >>593 >それほどパターンが多くはないがひとつの原則で表せるわけでもない。 キメぇよw
595 名前:デフォルトの名無しさん mailto:sage [2025/08/23(土) 09:17:36.36 ID:rBYkDYvT0.net] 構造的部分型とか静的ダックタイピングって呼ばれるやつ?
596 名前:デフォルトの名無しさん [2025/08/23(土) 13:12:32.34 ID:wVRYzYK20.net] >>591 int r1; float r2; long r3 r1, r2, r3 = foo(); って書きたいですね。Pythonみたく
597 名前:はちみつ餃子 mailto:sage [2025/08/23(土) 13:15:39.41 ID:DefMPT1k0.net] 代入のときは tie を使う。
598 名前:デフォルトの名無しさん [2025/08/23(土) 15:01:16.09 ID:p3yrvAiP0.net] テンプレートの黒魔術で脳汁出てからが本番
599 名前:デフォルトの名無しさん mailto:sage [2025/08/23(土) 15:37:03.06 ID:T+HzfXMC0.net] >>596 別の言語っぽくって考えは捨てた方が身のため
600 名前:デフォルトの名無しさん mailto:sage [2025/08/23(土) 19:08:06.22 ID:VwZegIlc0.net] 666!
601 名前:デフォルトの名無しさん [2025/08/23(土) 19:56:19.30 ID:k0uySdFmd.net] struct { int r1, float r2, long r3 } t; t = foo(); って描きたい struct に tuple からのコンストラクタを実装すれば良いのかな
602 名前:はちみつ餃子 mailto:sage [2025/08/23(土) 20:18:30.70 ID:CHT0FIec0.net] >>601 最初から foo がその型で返せばいいんでないの?
603 名前:デフォルトの名無しさん mailto:sage [2025/08/24(日) 12:07:46.50 ID:HqphwiLf0.net] C言語から続くカンマ演算子が分かってないんでは?
604 名前:デフォルトの名無しさん mailto:sage [2025/08/24(日) 12:09:48.21 ID:gU3L8vdd0.net] Pythonあがりだから型を定義する意味がわかってないんだと思う
605 名前:デフォルトの名無しさん mailto:sage [2025/08/25(月) 07:55:54.04 ID:O202BBJ90.net] a=10 a=’hello' 翻訳しながらだからできるんだろうけどね。
606 名前:デフォルトの名無しさん mailto:sage [2025/08/25(月) 08:19:19.75 ID:X23BjBGY0.net] >590 左辺にも現れるからじゃね?
607 名前:初心者プログラマー [2025/08/28(木) 17:50:07.17 ID:GULY1B8W0.net] cppでbazelでmediapipeのビルド方法を教えてくれる方はいませんか? 自分の環境 Visual Studio Community 2022 Windows11 64 ビット scoopでbazel 5.3.0 Python 3.10.0
608 名前:青木康善 mailto:sage [2025/09/07(日) 03:16:03.97 ID:Fgms30k2a.net] なんか、javaより簡単に思えてきました。
609 名前:はちみつ餃子 mailto:sage [2025/09/07(日) 06:54:14.37 ID:Ur1gsBeL0.net] そうか。
610 名前:デフォルトの名無しさん mailto:sage [2025/09/07(日) 07:39:38.11 ID:yhbLpr+z0.net] obj1=obj2; の後obj2を変更すると、obj1が書き換わってまってびっくりして その後、Javaが怖い親父です。
611 名前:デフォルトの名無しさん [2025/09/07(日) 13:56:14.79 ID:ZFShxqYO0.net] C/C++もポインタを代入するとそうなるよ
612 名前:デフォルトの名無しさん mailto:sage [2025/09/07(日) 15:17:34.87 ID:DiKqvn8B0.net] この親父他の言語ほぼ使えんだろ
613 名前:デフォルトの名無しさん [2025/09/07(日) 15:34:33.99 ID:AK/wIzqla.net] 普通 https://ideone.com/wGzMHW p=[3,1,2] q=p p[1]=0 print(q)
614 名前:デフォルトの名無しさん mailto:sage [2025/09/07(日) 16:53:15.89 ID:2DaEs5aKM.net] >>610 >>613 それはオブジェクトへの参照の競合が起きてる それぞれで書き換え更新または読み取り中の書き換えをすることでスパゲッティなコードを招いてしまう その競合をコンパイルエラーにして防いでくれるのはRustだけだと思う
615 名前:デフォルトの名無しさん mailto:sage [2025/09/07(日) 17:20:59.28 ID:yhbLpr+z0.net] >>614 c/c++なら、ポインタなのか参照なのか見ればわかるし、 まずコンパイラが型をチェックしますんで。はい
616 名前:デフォルトの名無しさん mailto:sage [2025/09/07(日) 17:34:06.57 ID:5bTmv8Qp0.net] 参照メインの言語で書き換えを頻繁に行うとそりゃ事故るよ、注意力にも限界がある 値の書き換えをするならC++のように変数が直接値を持つ言語がいいし 参照をメインにするなら関数型言語のようにimmutableを基本にするべきだ
617 名前:デフォルトの名無しさん mailto:sage [2025/09/07(日) 18:17:46.03 ID:kASsF2K3r.net] ないしは、q=p; ってしたときに、pがダメになってくれるか
618 名前:デフォルトの名無しさん mailto:sage [2025/09/07(日) 22:03:02.60 ID:2DaEs5aKM.net] >>615 C++では参照の競合があってもエラーとならず安全性は保証されないよ 例えば以下の挙動 std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7}; int& fifth = v[5]; v.push_back(100); std::vector<int> w{8, 8, 8, 8, 8, 8, 8, 8}; fifth = 555; std::cout << "v[5] = " << v[5] << std::endl; std::cout << "w[5] = " << w[5] << std::endl;
619 名前:デフォルトの名無しさん mailto:sage [2025/09/08(月) 07:59:15.17 ID:It1Ffdlu0.net] >>618 これわ別問題じゃないのですか。 にしても、おとろしい push_backされた時点で再構築されて、新規作成のオブジェクトの要素を保持してしまったで合ってますか?
620 名前:はちみつ餃子 mailto:sage [2025/09/08(月) 10:27:54.64 ID:bx3qX9/R0.net] 状況を一から説明すると…… これは fifth が古い無効になった場所を参照する可能性があることが問題。 std::vector の各要素は連続した空間に配置されることが保証されている。 要素の増減でその場所の都合が悪くなれば再配置される可能性があり、 再配置が起こったときは要素を指していたイテレータや参照は無効になるというルール。 無効なイテレータや参照を通じてアクセスしたら何が起こるかわからない。 再配置が起こる可能性がある操作については個々に仕様に書かれているけれど、 キャパシティを変更する (可能性がある) ような操作はどれも再配置が起こりえると覚えておけばいい。 そんでもってこれのややこしいところは「可能性がある」ってところで、 キャパシティをどれくらい拡大するか実装によって差があるし、 状況によっては場所を移動せずに大きさを伸ばせるかもしれない。 つまり問題が顕在化しないかもしれない。 一般論として倍々に延ばす実装がよく知られているからこの例では最初に要素を 8 個にして 顕在化しやすいようにしたんだろう。
621 名前:デフォルトの名無しさん mailto:sage [2025/09/08(月) 10:47:28.92 ID:It1Ffdlu0.net] >>620 どもです。要素数8ってのもさすがって感じでした。
622 名前:デフォルトの名無しさん mailto:sage [2025/09/08(月) 22:24:25.56 ID:EA0JjXQaM.net] >>620 今回の問題に限ればその通り ただし問題の本質は二つの参照(変数fifthとpush_back呼び出し時の参照)を使ったこと 今回はダングリング参照で問題を分かりやすく示したがメモリ問題もvectorも本質ではなく任意のデータに対する参照で問題が起きる 既に参照fifthを持つ状況で同じデータを指す別の参照を関数push_backに渡してデータが書き換えられた 参照fifthが指す値は当初から値が変更されてしまったりダングリングで無効な値になる可能性がある これが二つの参照の競合による問題で値がいつの間にか書き換わってしまっていることでバグも誘発する 両方の参照が書き換えを伴わないreadonlyの時のみ安全になる 片方もしくは両方の参照が書き換えを伴うと安全でなくなる
623 名前:デフォルトの名無しさん mailto:sage [2025/09/08(月) 23:06:53.70 ID:HoahUzIM0.net] 再配置が行われるものに参照使って、その生存期間を超えてアクセスするのは未定義動作になるわな。C++に慣れてればそんなコードは書かないが、初級者向けではない。readonly より、lifetime の問題でしょう
624 名前:デフォルトの名無しさん mailto:sage [2025/09/09(火) 00:29:11.16 ID:TMUamLpP0.net] 参照が無効になる条件は規定されてるし、先にcapacity設定するとか避ける方法も用意されてる 「問題の本質」とやらはただのライブラリ仕様の無理解だろ 分かりにくいとか間違えやすいとかの批判なら分かるけど
625 名前:デフォルトの名無しさん mailto:sage [2025/09/09(火) 07:24:41.95 ID:DVL1/TmTM.net] >>623 >>624 申し訳ないがcapacityや再配置の話はしていない lifetimeや参照が無効になる話もしていない まずそれらを頭の中から消し去って考えよう 元々の話である同一データに対して参照が二つ持った時の話のみをしている もちろんvectorは登場してもしなくてもいい
626 名前:デフォルトの名無しさん mailto:sage [2025/09/09(火) 07:29:27.85 ID:DVL1/TmTM.net] 元々の話とは>>610 や>>613 でこれらが参照の競合の最も単純な例 様々な言語で発生してもちろんC++でも生じる 同一データに対して複数の参照を持つと他の参照によっていつの間にか指していたデータの値が書き換わってしまう これがバグやコードのスパゲッティ化を引き起こす最も大きな原因の一つ そのためreadonlyでない限り複数の参照を避けるのが好ましい そのため競合する参照を禁止している言語もある
627 名前:デフォルトの名無しさん [2025/09/09(火) 10:47:02.21 ID:g327vfuJd.net] readonlyでない競合する参照を禁止している言語もある
628 名前:デフォルトの名無しさん mailto:sage [2025/09/09(火) 12:16:08.28 ID:iPWQv8Oa0.net] はいはい線型論理言いたいだけ
629 名前:デフォルトの名無しさん mailto:sage [2025/09/10(水) 00:51:51.50 ID:BnR46AnOa.net] >>618 これはvにpush_backしたところでキャパ超えて別の場所にリアロックされ、ともない元のvの領域が空になって、即座にwがスポンとそのvが元あった場所に配置されたってことなのですか?
630 名前:デフォルトの名無しさん mailto:sage [2025/09/10(水) 02:12:52.51 ID:IF/zSGeMd.net] そうだよ。 規格上は何の保証もないから、処理系とかによっては全然違う結果になるかもしれないけど。
631 名前:629 mailto:sage [2025/09/10(水) 10:07:49.21 ID:3vsmg39oa.net] >>630 どうもありがとう
632 名前:デフォルトの名無しさん [2025/09/10(水) 10:13:08.62 ID:zTYInGVv0.net] >再構築されて新規の要素を保持してしまったで合ってますか こう聴かれると「違う」と返事したくなる
633 名前:デフォルトの名無しさん mailto:sage [2025/09/10(水) 18:40:20.64 ID:Vv9EwJFH0.net] 未定義動作だからな たまたま鼻から悪魔が出る代わりにそうなっただけだ
634 名前:デフォルトの名無しさん mailto:sage [2025/09/10(水) 22:18:27.54 ID:RAO/BxQt0.net] 参照の競合という用語に違和感。並行性に関わる競合状態 (race condition) の話をしようとしているのか?
635 名前:デフォルトの名無しさん mailto:sage [2025/09/10(水) 22:31:03.50 ID:BZTqerG60.net] してない
636 名前:デフォルトの名無しさん mailto:sage [2025/09/22(月) 23:24:45.15 ID:ZT49UQS30.net] でわ 簡単?な話題を。 int data{}; ってやります? int data{0}; ってやります?
637 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 06:55:15.77 ID:S9rfzcfC0.net] int data = 0; ってやる
638 名前:はちみつ餃子 mailto:sage [2025/09/23(火) 10:47:53.44 ID:0b1Ncss10.net] auto data = 0; とか、型が明示的なのが好みなら auto data = int(); といった選択肢もある。 私は int data = 0; 派だけど。
639 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 10:57:08.68 ID:NP1ck5iL0.net] >>638 autoを使う理由は?
640 名前:はちみつ餃子 mailto:sage [2025/09/23(火) 11:12:21.28 ID:0b1Ncss10.net] >>639 暗黙的であれ明示的であれ初期化子に型があるのだからそれとは別にもう一度型を書くのは二度手間と言える場合がある。 どういう考え方をとるべきなのかは場合による。
641 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 11:17:00.61 ID:NP1ck5iL0.net] >>640 autoは曖昧だから、ゆるいプログラム用だね シビアなプログラムは無理
642 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 12:32:51.63 ID:zwbfimRS0.net] >>638 イテレータの返しを受けるオブジェクトはauto使うと便利みたいな
643 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 14:23:55.04 ID:SO+rqWsF0.net] >>641 テンプレート作るときには必須になる場合もある ゆるいって理解は雑
644 名前:はちみつ餃子 mailto:sage [2025/09/23(火) 14:48:06.92 ID:0b1Ncss10.net] 前提条件を変えると何でも言えてしまう。 とりあえずここでは発端は >>636 なのだから変数 data の型が int であり (多相にはしない) 内容はゼロで初期化するという狭い仮定を置いたほうがよかろう。 auto を持ち出したのは変に話題を曲げてしまったな。すまぬ。
645 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 20:34:08.12 ID:3YWvMRZsr.net] 今北 いまさら人に聞けない auto って、右辺の型もそのまま左辺にコピーしてきてよ、って感じで使ってるんだけど その認識で間違ってない? 落とし穴とかある?
646 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 20:39:56.49 ID:7uroOMzl0.net] 右辺が式の場合もあるし その時自分が思ってた型とautoの型が一致するとは限らないところとか
647 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 21:26:37.10 ID:qWXNEai60.net] autoで手抜きしすぎるとあとでソース追うときにエライ苦労することあるから気を付けろよ
648 名前:デフォルトの名無しさん mailto:sage [2025/09/23(火) 21:34:42.79 ID:NP1ck5iL0.net] >>647 Pythonとか、 型が書かれてないから追いづらいよね
649 名前:はちみつ餃子 mailto:sage [2025/09/24(水) 02:24:38.07 ID:hHyw0Adk0.net] >>645 その認識でおおよそ正しいが変則的な部分もある。 auto foo = { 1, 2, 3 }; みたいに書くと initializer_list に推論されたりするのは知らないとちょっとびっくりするかもしれない。 それと修飾子などを組み合わせで使うことも出来る。 const auto* bar = &baz; みたいに。
650 名前:デフォルトの名無しさん mailto:sage [2025/09/24(水) 07:20:39.19 ID:tMR45KsJ0.net] >>649 何の目的であるの? C#的にゆるくなるだけだな…
651 名前:はちみつ餃子 mailto:sage [2025/09/24(水) 08:23:07.29 ID:yL+cLVSS0.net] >>650 ゆるいというのがどういう意味で言ってるのかわからないからなんとも言えない。 特に有用なのはテンプレート内で、たとえば template<class T> void foo(T x) { auto bar = baz(x); // baz は関数テンプレートだとする // ここでなんやかんや } みたいなのがあるとき auto を使わずに型を合わせて書こうとすると template<class T> void foo(T x) { decltype(baz(x)) bar = baz(x); // baz は関数テンプレートだとする // ここでなんやかんや } みたいになってわずらわしい。 初期化子の型をそのまま持ってくれば良いときに型を明示しても可読性に貢献しないし、簡便な記法があると楽。
652 名前:デフォルトの名無しさん [2025/09/24(水) 12:48:43.78 ID:4f1PT/5nH.net] std::make_sharedとか使うと行が長くなりがちだからauto便利
653 名前:デフォルトの名無しさん [2025/09/24(水) 23:18:51.30 ID:OQUpbPvH0.net] autoでしか出来ないこともあるから奥が深い
654 名前:デフォルトの名無しさん mailto:sage [2025/09/24(水) 23:47:45.55 ID:wXWMV3aG0.net] 罠仕様が仕込まれてるってだけでは
655 名前:デフォルトの名無しさん mailto:sage [2025/09/25(木) 06:56:54.48 ID:iHrblX0Rr.net] Rust派に言わせれば、C++が罠らしいぞw でもそのC++が、今の俺を生んだ
656 名前:デフォルトの名無しさん mailto:sage [2025/09/25(木) 16:58:42.68 ID:tx4jrZ/E0.net] 有用なときもあるけど、ライブラリ用のコードで乱発するとメンテナンスが大変 可読性メンテナンス性を考えるなら、冗長でない限りはちゃんと書いた方がいい >>651 それもbaz(buz?)の戻り値の型はTから導出出来るんだから、よほどややこしくない限りはそれ(decltypeで手抜きせずに)を書いた方が可読性メンテナンス性の面では良い
657 名前:デフォルトの名無しさん mailto:sage [2025/09/25(木) 17:00:57.66 ID:/3f9OB3n0.net] >>656 お前テンプレートプログラミングの素人さんだよね
658 名前:デフォルトの名無しさん mailto:sage [2025/09/25(木) 20:40:29.81 ID:tx4jrZ/E0.net] >>657 自己紹介乙w Expression Template使って線形代数のライブラリ作った人間だが、ETで利用者がauto使うとどういう問題が起きるか答えてみ まさか分かりませんとか言わないよな? テンプレート使ったライブラリ(てか標準ライブラリ)を"利用する"しかしたことのない人間が調子に乗るな
659 名前:デフォルトの名無しさん mailto:sage [2025/09/25(木) 20:43:04.50 ID:nRsNESWS0.net] なんか「その理論を作ったのは私ですが」みたいなものを感じる 技術発表の際の怖い質問とかなんとかのやつw
660 名前:デフォルトの名無しさん [2025/09/25(木) 20:43:46.25 ID:ofoI5OnU0.net] 言葉ならなんとでも言えるわな
661 名前:650 mailto:sage [2025/09/25(木) 20:44:29.25 ID:hN2fGih80.net] >>651 ふーん 便利だね でも、templete自体が何だか好きじゃないわ…
662 名前:650 mailto:sage [2025/09/25(木) 20:46:08.51 ID:hN2fGih80.net] >>656 ちゃんとっって、型を? 型が書いてないと、パット見でわからないよね…
663 名前:デフォルトの名無しさん mailto:sage [2025/09/25(木) 20:54:22.86 ID:tx4jrZ/E0.net] >>662 そう&同感 ぱぱっと書いて何やってるかもすぐ分かるような場面(戻り値がイテレータとか)ではそりゃautoでいいと思うけどねぇ
664 名前:デフォルトの名無しさん mailto:sage [2025/09/25(木) 21:36:33.99 ID:SUv+BSiy0.net] 今ならconceptを使うのが筋が良いんだろうな 他の言語みたいに型制約を書かずにジェネリクスを使えるけど、これは良くも悪くもだよね 楽と言えば楽だけど
665 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 01:34:47.37 ID:aJA0eUoF0.net] >>658 リポジトリ晒して まさか出せませんとか言わないよな? テンプレート使ったライブラリ(てか標準ライブラリ)を"内製する"しかしたことのない人間が調子に乗るな
666 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 01:53:11.78 ID:IAhZoqBcM.net] >>658 端的に言って > それもbaz(buz?)の戻り値の型はTから導出出来るんだから、 ここだよ 関数テンプレートなんだから型が導出できるとは限らない なぜお前は断言したのかな? 導出できない例にぶち当たったことがないからだよな
667 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 07:26:52.27 ID:uQKo8FSG0.net] >>665 >>668 煽ればタダで教えてもらえると思ってるいつものアホか >導出できない例 あるわけないだろどうやって実体化するんだよwwwwww
668 名前:デフォルトの名無しさん [2025/09/26(金) 08:15:01.31 ID:FGFv/5hn0.net] conceptはテンプレートだけじゃなく普通の変数制約にも使えればなぁ。 継承がほとんどいらなくなる。
669 名前:デフォルトの名無しさん [2025/09/26(金) 10:28:59.69 ID:UkFmEBgMa.net] >>647 判ります
670 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 11:12:51.14 ID:TfDLIQWg0.net] 手抜きというか情報を重複させないためにはautoが必要 苦労するのは型情報を追えないツールが悪い
671 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 11:53:52.65 ID:IRzSnzQy0.net] >>648 ああ、おそろしいあの言語は 素人にはササッと組めて楽チンだろうけど大掛かりなものは無理だろうな 想像しただけで脳が震えて耳から溶けて出てきそうだ
672 名前:はちみつ餃子 mailto:sage [2025/09/26(金) 12:02:33.14 ID:E9e6Z1Un0.net] expression template を auto で受けるとまずいってのは Eigen みたいな設計の話かな。 あれはムーブがない時代の設計だから一時オブジェクトの参照を保持してしまう (先に一時オブジェクトが解体されて寿命管理が破綻する) のが問題なのであって、解決のための仕組みが与えられたにもかかわらずそれを使ってない設計が悪い。 expression template の仕組み上でどうしても解決できないというわけではないし auto のせいでもない。 ムーブのコストすら許容できないだとか、古い C++ (C++03 以前) もサポートしなきゃならないみたいな事情があるなら「すまんけどこのライブラリを使うときは注意して」というべき筋合いの話で、「auto なんか使っとるからじゃ!」みたいな態度はおかしいだろ。
673 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 12:09:27.62 ID:uQKo8FSG0.net] >>672 >のが問題なのであって 違う。ETの場合、関数(演算子オーバーロード含む)が返すのは、式の構造を表すオブジェクトなのでそれをautoで受けると式の展開が行われず、計算処理の無いコードになってしまう それを逆手に取ってauto経由で展開のタイミング遅らせることもできるけどね あとETの利点はムーブどうこうで解決できる問題だけではないし、 誰も「ETを万人が使うべき」だなどと言っとらんよ、何が気に入らんかったの? で、はちみつお前いつも「知ったかぶりしていい加減なことを言う奴」に怒ってる割に、自分も同じ事してるよな
674 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 12:11:01.51 ID:uQKo8FSG0.net] あと >「auto なんか使っとるからじゃ!」 一言も言ってないんだが。流れ読み直しておいで
675 名前:はちみつ餃子 mailto:sage [2025/09/26(金) 12:54:00.88 ID:E9e6Z1Un0.net] >>672 > autoで受けると式の展開が行われず、計算処理の無いコードになってしまう 書いてなかったが評価タイミングは適当な関数で明示的にする前提を置いてた。 未定義を踏むのは他の何と比べても駄目だ。単に思ってた結果と違ったなんてのは重要じゃない。 > 誰も「ETを万人が使うべき」だなどと言っとらんよ、何が気に入らんかったの? 日常的には使わないケースだからこそだ。 それが auto の問題点のように挙げられてただろ? ライブラリのほうが C++ の自然な習慣に合わせるのが筋なのにさ。
676 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 13:15:19.27 ID:4po4sxfpp.net] >>657-658
677 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 13:19:26.24 ID:4po4sxfpp.net] >>675 あと、ETで式の評価が発生するのは関数の呼び出し時ではない。どうでもいいけど あと俺が作ったのは4次元まで(行列なら4x4まで。ゲーム用なので)だからヒープ使わんのでそもそもムーブどうこうは関係無いし、勝手によそのライブラリの未定義の話を持ってこられても困る
678 名前:はちみつ餃子 mailto:sage [2025/09/26(金) 13:57:45.37 ID:E9e6Z1Un0.net] >>677 eigen は例として話題に出したつもりだったが余計だったな。 端的に主旨を言えば expression template の原理的には auto で受けれるように作ることは可能、かつその方が親切な作りだろうという話をしてる。 お前がどんな設計をしたのかなんてそれこそ俺には知ったことじゃないし、知りようもない。 お前のライブラリで auto で受けれないのはお前がそう設計しただけの話なので、 それを根拠に auto がどうこう言ってもなんの足しにもならん。
679 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 14:04:20.28 ID:4po4sxfpp.net] >>657-658 ETの話はここで出した。 で、俺のautoの使い方に関する意見は>>656 だ 自分が何をやってるか良く考えてからレス書き直せ
680 名前:はちみつ餃子 mailto:sage [2025/09/26(金) 14:08:11.66 ID:E9e6Z1Un0.net] >>679 悪い設計のせいで利用者に不自然な書き方を強いるライブラリを作ったという話だということは理解してる。
681 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 14:13:42.65 ID:4po4sxfpp.net] あといちいち知ったかぶってるバカに教えてやるのも腹が立つが、普通数値演算でET使うときは代入演算子やコンストラクタに式を渡した場所で初めて式を展開するんだよ (autoでわざと評価を遅延させることも可能だと書いただろアホ) Eigenでも多分そう もちろんboost::spiritとかの構文解析ならパース処理の関数に渡すまで展開しないだろうが
682 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 14:14:19.90 ID:4po4sxfpp.net] >>680 不自然なのはお前の、「スキルに見合わない自尊心」だと思うぞ
683 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 14:24:32.42 ID:4po4sxfpp.net] バカが屁理屈書いてきそうだから再三言うが、>>658 は>>657 を叩くために出した問いに過ぎない 「意図しないコードになる」という話 これだからお前には絡みたくないんだよマジ鬱陶しい
684 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 17:03:47.95 ID:iKKvsVQ80.net] お前ってのははちみつのこと言ってるのかね? 自分から絡んどいて何言ってんだろうコイツとしか思えんけど
685 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 17:53:41.26 ID:uQKo8FSG0.net] >>684 で、>>666 の導出出来ない例って何?www
686 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 19:18:42.84 ID:+hZbpaFa0.net] >>685 ラムダの型導出できないだろ? なんでこんなのも知らんのにえらそうにしてんの? あと https://wandbox.org/permlink/q5sTF1hp76f7jpnq とかな この例でfooでもif constexprを使えばautoはなくせるがそんなことやって可読性とかほざけない 他にもパターンあるぞ 謝罪してお前が作ったらしいヘボライブラリ公開したら教えてやってもいいぞ
687 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 19:32:01.31 ID:uQKo8FSG0.net] 屁理屈にも程がある 導出出来なきゃどうやって実体化するんだよ、Tしかテンプレートパラメータが無い状況でT以外に依存するものがあるのか? まさか結果がTに依存するテンプレートになったら「導出出来てない」とかほざくの? Tに依存するコンテナのイテレータと何も変わらんよそれ
688 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 20:12:50.41 ID:uQKo8FSG0.net] てかその例でauto使わずに戻り値格納するのにif constexpr使うしかないと思ってるとかどんだけ経験不足なんだ・・・(はっきり処理分けする必要がある場合を除く) そんなクソみたいな例ならさすがにdecltypeかauto使いたくなるが(そもそも使うなと言ってないんだが)、conditionalも知らんのかお前は 必死に探してきてご苦労さん
689 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 20:41:40.17 ID:aJA0eUoF0.net] あの…そろそろ言っとくが おもろいこと書いたヤツが優勝な? 2ちゃん5ちゃんの原則だぞ
690 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 20:46:36.85 ID:uQKo8FSG0.net] >>665 はおもろいと自分で思ってんの?w
691 名前:デフォルトの名無しさん mailto:sage [2025/09/26(金) 20:59:48.54 ID:+hZbpaFa0.net] >>687 おじいちゃん、ラムダの例で詰んでんのわかる? わかんない? わかんないかぁ
692 名前:デフォルトの名無しさん mailto:sage [2025/09/27(土) 00:06:32.90 ID:ov4hhnsF0.net] やっぱautoはゆるいね C#とかPython的な感じ…
693 名前:デフォルトの名無しさん mailto:sage [2025/09/27(土) 05:08:15.66 ID:rNLW6nkI0.net] C++は自由なんだよ 変な風にも使えるし、傍で見てたらめちゃくちゃにもなる
694 名前:デフォルトの名無しさん mailto:sage [2025/09/27(土) 05:36:45.87 ID:p3kzti810.net] 自分が使った方がいいと思った時は使う。 しかないよ。後は規約や上司に従うぐらいか。
695 名前:デフォルトの名無しさん mailto:sage [2025/09/27(土) 11:22:44.98 ID:0x5FUGdK0.net] 久々にC++スレらしくなってておっちゃん楽しいよ
696 名前:はちみつ餃子 mailto:sage [2025/09/27(土) 17:37:01.17 ID:nSvwU9re0.net] >>681 コンストラクタや代入演算子で実際の計算を起動する方式も支持があるのは知ってるよ。 だからその代表例として有名どころの Eigen を話題に出したのだし、そこに齟齬はない。 その上で唯一の方式ではないし悪い設計だと言ってる。 私に反論するならどうしてそんな方式を取るのか利点 (悪い設計ではない理由) を説明すべきだった。 「数値計算で expression template を使うときは普通」なんて情報量ゼロのことを書かれても何の意味も感じられない。 コンストラクタや代入演算子をトリガーにするのは expression template を最適化として使う考え方だ。 つまり見かけ上は普通に式を書いてるだけなのに実は高速化しているというのがキモで、普通の式である「かのように」見える抽象化に意味がある。 実際の型を意識せざるを得なくなった段階で抽象化は破綻してる。 auto を使ったら何が起こるかを意識しなければならないのはライブラリ設計の失敗なんだよ。 隠れていたりいなかったりする半端な抽象化層を悪い設計と呼ぶのは間違ってるか? > 再三言うが、>>658 は>>657 を叩くために出した問いに過ぎない > 「意図しないコードになる」という話 そんなので意図しないコードになってしまうような作りのライブラリは出来が悪いという話なのはかわらん。 様々な事情に配慮してそうならざるを得ないということもあるというのならわかるが、 そうじゃなくて「それが普通なんだ」と思い込んだ狭い見識での判断なんだろ? 型を書くか auto にするかはスタイルの問題で、どちらを使うかで挙動が切り替わってしまうような設計のライブラリが本当にまともか?
697 名前:デフォルトの名無しさん mailto:sage [2025/09/27(土) 17:54:13.79 ID:iipvXy1W0.net] よほど悔しかったんか知らんが、恥の上塗りやめたら? autoをC++に取り込んだ人達は、お前が調子に乗るために提案したわけでも採用したわけでもなかろうよ
698 名前:デフォルトの名無しさん [2025/09/27(土) 19:49:03.02 ID:k7oMySGea.net] >>696 八光さんに同意だけど それだとC++が設計ミスと言う結論になりかねない
699 名前:はちみつ餃子 mailto:sage [2025/09/27(土) 20:00:56.28 ID:nSvwU9re0.net] C++ が設計ミスだらけなのは今更な話だろ。
700 名前:580 mailto:sage [2025/09/28(日) 18:27:48.51 ID:MSQtxm6D0.net] 解決しますた!
701 名前:はちみつ餃子 mailto:sage [2025/09/28(日) 19:20:47.09 ID:pjQge+jC0.net] そうか。
702 名前:デフォルトの名無しさん mailto:sage [2025/09/29(月) 19:03:56.70 ID:ALxfRd8b0.net] VSCode(WSL)のclang-tidyで質問です 関数にconst付けるのを警告する「readability-make-member-function-const」って奴ですがDoSave()関数にも警告が出ます 可能ならgetterのみに付けたいのですが皆さんこれはどうされてますか? 無効にしてるか、無視してるか、const付けてるか、その他何かやってますか? C++の環境構築は初めてなので助言をいただけるとありがたいです よろしくお願いします
703 名前:デフォルトの名無しさん mailto:sage [2025/09/29(月) 19:56:30.29 ID:BDszbKFL0.net] こういうこと? 要はconst性を「セーブさせたくない」という符丁に使いたいのかな class Hoge; // DoSave()持ち void foo(Hoge& h1, const Hoge& ch2) { h1.DoSave(); //ゆるす ch2.DoSave(); //ゆるさない } そんな変なことやめとけとしか思わないけど、どうしてもそうしたい理由があるなら言ってみ
704 名前:デフォルトの名無しさん mailto:sage [2025/09/29(月) 20:49:50.37 ID:Qgirjd9Z0.net] const_cast<Hoge*>(&ch2)->DoSave();
705 名前:デフォルトの名無しさん mailto:sage [2025/09/29(月) 22:22:15.60 ID:ALxfRd8b0.net] >> 703-704 すみませんサンプルを載せるべきでした ソース: double Point::X(){return x;} void Point::X(double value){ x=value;} ヘッダ: static Point { public: double X(); void X(double value); private : double x=0; }; clang-tidy を実行すると「double Point::X()」のX部分で「Method 'X' can be made const (readability-make-member-function-const)」という警告が出ます 調べてみると「constを追加して、内容が変更されないことを明確にすべき」らしいです ソース:double Point::X() const {return x;} ヘッダ:double X() const; 上記だけなら問題無いのですが、下記のような関数にも同じ警告が出てしまいます ソース:void Sample::DoSave(){ ファイルの保存処理 } ヘッダ:void DoSave(); この場合、getterではなく処理なので、const は付けるべきでは無いと考えてます そこで質問ですが、clang-tidy で静的チェックを行う場合「readability-make-member-function-const」の扱いはどうすべきなのか気になった次第です 「無効にすればいいのか」と思いながらも、C#のプロパティではないので、「C++は変更されないことを明示した方が分かりやすいのか?」とどのように設定すべきか悩んでいます よろしくお願いします 環境は下記:VSCode、ubuntu 22.04 (WSL)、C++ 17、clang-tidy-15
706 名前:デフォルトの名無しさん mailto:sage [2025/09/29(月) 23:01:05.35 ID:jk3QzjEU0.net] NOLINT
707 名前:デフォルトの名無しさん mailto:sage [2025/09/29(月) 23:04:57.63 ID:rfIMSjI90.net] >>705 その場合const付けたほうが良い理由は「変更されないことを明示」することより constのインスタンスに対してその関数を呼べなくなることでは? ↓はエラーか警告(どっちかは忘れた)になると思う(constオブジェクトの非constメンバ関数は呼び出せない) void SaveData(const Sample sample) { sample.DoSave(); } void Sample::DoSave() const { ファイルの保存処理 } にしておけば、DoSaveは呼び出せる
708 名前:デフォルトの名無しさん mailto:sage [2025/09/30(火) 01:33:12.30 ID:Xmjd+d/v0.net] 処理だからconst付けないんじゃなくて、そのメンバ関数がPointクラスの中身を書き変えないことを保証するためにメンバ関数の後ろにconstは付ける つまり、Save処理はPointクラスを特段変更するメソッドではないだろ? だったらconstは付けるべき
709 名前:デフォルトの名無しさん mailto:sage [2025/09/30(火) 07:07:46.33 ID:NaKN2pJV0.net] >>705 つまり、constを本来の意味(中身を変更するかどうか)ではなく「getterであるかどうか」を示すラベルとして使いたいってことでしょ? で、何を持って「getterであるかどうか」はあなたの頭の中にしかない定義であって、そのlintはもちろんコンパイラもエディタも世のライブラリも知ったことではない それらをオレオレconstラベルに適合させるためにどうしたらいいか?というのがあなたの問うていることだ やっぱりどうしてそんなことがしたいのか全く理解できない
710 名前:はちみつ餃子 mailto:sage [2025/09/30(火) 08:58:44.76 ID:0fqHawiZ0.net] >>705 オブジェクトがなんらかのストレージを抽象化したものであると考えたらそのオブジェクトが const であるときはセーブ機能を使えないようにしたいというのはわからんでもない。 実際の管理は他の場所でやっていて窓口に過ぎないならメンバ関数に const を付加可能 (だがそうしたくない) なこともあるだろう。 それが良い設計かどうかは脇に置いてそうすることに決めたときに clang-tidy の警告はどうすればいいのかということなら、 例外的な状況なので例外的なものとして無視してもらうしか仕方ないんじゃないか。 NOLINT コメントを書いておくと clang-tidy はその箇所については警告を抑制してくれるよ。
711 名前:デフォルトの名無しさん mailto:sage [2025/09/30(火) 10:38:19.22 ID:Dzyyn8xKd.net] >>706-710 御返事がおそくなりすみません ご意見ありがとうございます 自分の理解不足と設計思想が間違ってるまたはずれてるんだと理解しました ・「readability-make-member-function-const」の指示にしたがってconstを付けるのが良い ・更に言うと-fixオプションで自動付与するレベルの内容 ・だけどNOLINTで無視もできるよ(無視してるとは言ってない) ってことで理解しました 勉強になりました ありがとうございます
712 名前:デフォルトの名無しさん [2025/09/30(火) 21:38:35.37 ID:bXNPhBlr0.net] VC++20のテンプレート制約で不可思議なことが起きるのだけど、以下の二つは同じ意味だよね? 1だと目的通りTParentに該当static関数<T>があれば適用、なければスルーという挙動になるのだけど、 2だと無くても適用されちゃって他を探しに行かずにオーバーロード未解決に陥るんだけどどういうことだろう? 1 template<typename T, typename TParent> concept HasSizeGetter = requires { (size_t)TParent::template get_size<T>(); }; template<HasSizeGetter<TParent> T> static consteval size_t get_require_space() { return TParent::get_size<T>(); } 2 template<typename T> requires requires { (size_t)TParent::template get_size<T>(); } static consteval size_t get_size() { return TParent::get_size<T>(); }
713 名前:デフォルトの名無しさん [2025/09/30(火) 21:40:50.61 ID:bXNPhBlr0.net] ちょっと書き間違えてたけど1はget_require_spaceじゃなくてちゃんと2と同じくget_sizeね
714 名前:はちみつ餃子 mailto:sage [2025/09/30(火) 23:39:48.15 ID:0fqHawiZ0.net] >>712 オーバーロード未解決という形で現れるのはよくわからないけど この場合はその関数テンプレートを使わなくても (呼び出さなくても) エラーになるのが正しい挙動だと思う。 get_size は依存名ではないのでテンプレートの定義時 (テンプレート実引数を当てはめる前) に名前のルックアップが試みられて失敗する。 requires 節はテンプレート引数の妥当性を検証する仕組みなのでテンプレート引数をあてはめなくても式が不成立になるようなのはエラー。 というのが私の理解なんだけどあんまり自信はない……。
715 名前:はちみつ餃子 mailto:sage [2025/09/30(火) 23:47:38.26 ID:0fqHawiZ0.net] >>714 これは TParent::get_size が存在しない場合の話で、 TParent::get_size が存在するけど TParent::get_size<T> の展開に失敗する場合はちゃんと次の候補が選ばれるはず。 (手元に MSVC がないんだけどオンラインコンパイラで一応の動作確認はした。)
716 名前:デフォルトの名無しさん mailto:sage [2025/10/01(水) 06:54:56.10 ID:O1Ml42XO0.net] >>715 そう、2の場合でもTParent::get_sizeはあるけど<T>とはマッチしない場合にはちゃんと1と同じ挙動になるんだよね TParentにstaticなget_sizeが全くない場合だと1と2で挙動が変わってしまう でも2って1をインラインに直接書いたものであって同じ意味だよね? だからrequiresがどういう意味を持つかとか以前に挙動変わってくる時点で不可思議なんだよね
717 名前:はちみつ餃子 mailto:sage [2025/10/01(水) 07:43:33.30 ID:XKqCU3PC0.net] >>716 1 の場合は get_size は依存名だ。 そこで解釈が違うよ。
718 名前:デフォルトの名無しさん [2025/10/22(水) 12:58:32.68 ID:6nuMV8zc0.net] C++26から入るらしい^^と[::]という二つの演算子はどういう用途に使うものなのでしょうか?
719 名前:はちみつ餃子 mailto:sage [2025/10/22(水) 13:31:13.53 ID:/iXiQCcE0.net] >>718 リフレクションで検索したら色々な例がみつかるよ。 構文要素を値として取り扱う、本物のマクロだ。
720 名前:デフォルトの名無しさん mailto:sage [2025/10/22(水) 19:35:11.69 ID:t2Chdy11a.net] ^^ ↑ちょっと顔にみえる
721 名前:デフォルトの名無しさん [2025/10/22(水) 21:43:50.71 ID:q+0a8lK20.net] ^^;
722 名前:デフォルトの名無しさん mailto:sage [2025/10/22(水) 21:55:39.76 ID:tW3LNod+a.net] ^^;ゞ
723 名前:デフォルトの名無しさん mailto:sage [2025/10/22(水) 22:05:42.67 ID:b6F/3uj70.net] ^^::←グローバル名前空間のリフレクション値
724 名前:デフォルトの名無しさん mailto:sage [2025/10/23(木) 05:29:13.93 ID:HOQCmR4+0.net] v^^
725 名前:デフォルトの名無しさん [2025/10/23(木) 21:41:47.99 ID:FPW1mHao0.net] 山崎渉
726 名前:デフォルトの名無しさん [2025/10/24(金) 14:17:57.63 ID:nAYKU6CIa.net] GGは へへ ミミ
727 名前:デフォルトの名無しさん [2025/10/29(水) 17:48:11.20 ID:KY7jGttbH.net] Y(^_^)Y なんすかこれ 口が違う。覚えてる人修正して
728 名前:デフォルトの名無しさん [2025/11/11(火) 14:16:42.56 ID:crDtfQHZa.net] バルタン星人のひと元気かな
729 名前:デフォルトの名無しさん mailto:sage [2025/11/13(木) 14:20:45.09 ID:jo2+4JNJM.net] 多分基本的な質問ですまんけど、参照型のメンバー持ったクラスをmove対応させるのってどうやんのが定石? ポインタにするしかない?
730 名前:はちみつ餃子 mailto:sage [2025/11/13(木) 14:53:55.31 ID:bJCWdXAy0.net] >>729 その参照が差す先のオブジェクトの所有権 (最終的に後始末する責任) を持っている状況ということ? ポインタを交換する手法がよく使われるのはヌルで無効を表現してるだけなので所有権を持ってるかどうかわかるフラグを立てれるならなんでもいいよ。 型システム的に表現するなら optional と reference_wrapper を組み合わせるのがよいかな。(optional は参照を直接には保持できない。)
731 名前:デフォルトの名無しさん mailto:sage [2025/11/13(木) 22:00:10.45 ID:oKSfQs8Q0.net] いきなりわからんorz
732 名前:デフォルトの名無しさん mailto:sage [2025/11/13(木) 22:38:55.22 ID:PBCTneT3M.net] >>730 なるほどサンキュー でもoptionは省きたいところ moveしたあとは使わない前提でこれはUBになる? class A { std::reference_wrapper<const std::string> m_s; public: A(const std::string& s) : m_s(s) {} A(A&& rhs) : m_s(std::exchange(rhs.m_s, *(const std::string*)nullptr)) { } };
733 名前:デフォルトの名無しさん mailto:sage [2025/11/13(木) 22:48:43.43 ID:qvmNyT2p0.net] ・T*(ナマポ)にする Pros: 一番素直、ムーブ後状態をぬるぽで自然に表現できる。 Cons: メンバ使ってるとこで*付けたり.を->に書き換えたりが必要。deleteとか加減算とか好き勝手できちゃう。今どきナマポとかダサい。 ・std::unique_ptr<T>やstd::shared_ptr<T>にする Cons: 多分セマンティクス違う(もともとはヨソのオブジェクト覗いてるだけでしょ?) ・std::referrence_wrapper<T>にする Pros: 参照の置き換えという意味でこれも素直。 Cons: メンバ使ってるとこに.get()をつける書き換えが必要。ムーブがコピーになるので抜け殻に参照が残って潔癖な人だとキショい。 ・std::optional<std::referrence_wrapper<T>>にする Pros: 型的に一番真面目なので型マニアにっこり。 Cons: 書くのめんどい。「何これ?」って聞かれたときに説明めんどい(未来の自分含む)。.get()必要。 ・メンバはT&のままにしてムーブコンストラクタとムーブop=の方で対応する Pros: 既に使われてる所の書き換え不要。 Cons: ムーブ関数書くのとメンテし続けるのがめんどい。抜け殻に参照先残る。 どれも完璧じゃないから好きなの選んでいいよ
734 名前:デフォルトの名無しさん [2025/11/13(木) 23:01:27.30 ID:/tchf03X0.net] unique_ptrと同様のもの(unique_ref)を作ればいいんじゃねえのって話だろ ただしptrはnullptrで無効を表現してるから 代わりにフラグを用意する class unique_ref{ T& ref;//参照 bool isValid;//無効判定 //コンストラクタ unique_ref(T&r):ref(r), isValid(true){} //ムーブ コンストラクタ unique_ref(unique_ref&& a){move(a);} //ムーブ代入 unique_ref& operator=(unique_ref&& a){move(a);} move(unique_ref&&a){if(this!=&a && a.isValid) ref=a.ref; a.isValid=false;} } てなかんじかと 知らんけど
735 名前:デフォルトの名無しさん mailto:sage [2025/11/13(木) 23:06:32.01 ID:pKRh1I850.net] 参照なんて引数と演算子オーバーロード以外で使ってもいいこと無くね?
736 名前:デフォルトの名無しさん mailto:sage [2025/11/13(木) 23:07:03.58 ID:qvmNyT2p0.net] そもそも所有権自分で保持してるメンバがもともとT&ってことはないだろ どっか遠くのオブジェクトを見えるようにしてるだけでしょ? (それはそれで設計的に焦げ臭いけど置いとく)
737 名前:デフォルトの名無しさん [2025/11/13(木) 23:07:46.30 ID:/tchf03X0.net] もしくはunique_ptrをunique_refでラップしてしまうのが楽か
738 名前:デフォルトの名無しさん [2025/11/13(木) 23:10:58.33 ID:/tchf03X0.net] >>736 たまにある 外部リソース(たとえばファイルハンドル)を一時的にクラスに保持して使いやすくするとか なんにせよ寿命を明示的に管理しておかないと後でやばいことになる
739 名前:デフォルトの名無しさん mailto:sage [2025/11/13(木) 23:14:39.55 ID:qvmNyT2p0.net] >>738 ファイルハンドルだとして、それを管理するクラスがファイルハンドルの値自体を持たずにヨソに置いて参照するのはなぜ? やっぱり意味がわからない
740 名前:はちみつ餃子 mailto:sage [2025/11/13(木) 23:20:38.76 ID:bJCWdXAy0.net] >>732 UB になる。 ポインタと違って参照自体は無効を表現できないのが C++ の基本ルールであり、 reference_wrapper でもそれは同じ。 それでもあえてやるなら適当にダミーのオブジェクトを作っておいてそれを参照していたら無効ということにするというようなことをできなくはないが……それはそれでちょっと不恰好だよね。
741 名前:デフォルトの名無しさん [2025/11/13(木) 23:22:41.52 ID:/tchf03X0.net] >>739 クラス内部でちゃんと管理するのがいいんだけど時には関数内クラスを定義してちょっとしたことを行うこともある(かも) その時には所有権を一時的にでも委譲しなきゃならなくなる
742 名前:デフォルトの名無しさん mailto:sage [2025/11/13(木) 23:30:06.73 ID:qvmNyT2p0.net] >>741 ハンドルは外部で持ったままで、その関数内クラスにはハンドルの参照を渡す(関数内クラスの参照メンバを外部のハンドルで初期化する)って言ってる?それ委譲とは言わないよ 委譲したからにはそのリソースはその関数内クラスの消滅とともに消えないといけないけど、そうなったら外部で持ってたハンドルの実体はどうなるの? どんなケースを想定してるのか全然わかんない
743 名前:デフォルトの名無しさん mailto:sage [2025/11/14(金) 12:19:28.56 ID:YW3kWFexM.net] >>740 までもnull objectはよく使ってるからそれにするわ 個人的にはすっきり でもc++の参照っていらん子やん?って気がしてならない class A { static constexpr std::string s_empty_str{""}; std::reference_wrapper<const std::string> m_s; public: A(const std::string& s) : m_s(s) {} A(A&& rhs) : m_s(std::exchange(rhs.m_s, s_empty_str)) { } };
744 名前:デフォルトの名無しさん [2025/11/14(金) 17:06:33.25 ID:sw2A38eb0.net] >>743 型無しのnullpointerが型システム(機能保証)を破壊しているから、型を強要する参照は必要。
745 名前:デフォルトの名無しさん mailto:sage [2025/11/14(金) 17:48:56.23 ID:d/VpWy+aM.net] >>744 古くね? そういうのはoptional使えってのが最近のやり方でしょ?
746 名前:はちみつ餃子 mailto:sage [2025/11/14(金) 19:18:46.50 ID:YeCIJNF30.net] >>743 参照は色々な場面で有用ではあるが、 D&E によれば最初の動機は演算子オーバーロードだと書かれている。 オブジェクトをコピーする必要がない (値をコピーせずに場所を渡せば充分) ような状況で参照がなくポインタを使うならいちいち &a+&b みたいにして書く必要が生じる。 いかにも煩わしいだろう。
747 名前:デフォルトの名無しさん mailto:sage [2025/11/14(金) 19:55:59.90 ID:p/1JbX4j0.net] C++より古いの新しいの含めて多くの言語が採用してるように参照は引数でのみ使用可能で良かったと思うよ
748 名前:デフォルトの名無しさん [2025/11/14(金) 20:35:30.63 ID:/xnnTPah0.net] >>747 他の言語はともかく、C++の参照は引数に限定されてないですよ。 int a = 10; int* pa = &a;
749 名前:デフォルトの名無しさん [2025/11/15(土) 10:22:10.37 ID:ncudN0/g0.net] 747は、(実際の仕様はそうなっていないけど)引数でのみ使用可能なら良かったのに……という意味だと思うぞ。
750 名前:デフォルトの名無しさん [2025/11/15(土) 19:11:12.30 ID:lfrbAWbT0.net] ああ >使用可能で良かったと思うよ ではなく、 >使用可能だったら良かったのにと思うよ って事ですか
751 名前:デフォルトの名無しさん mailto:sage [2025/11/15(土) 19:25:57.81 ID:3JdS/6Ib0.net] カスみたいな読解力
752 名前:デフォルトの名無しさん mailto:sage [2025/11/15(土) 19:35:13.09 ID:QqRirP4Fr.net] そんなコミュ力高かったら、石が友達なんて言わない
753 名前:デフォルトの名無しさん [2025/11/15(土) 19:39:44.33 ID:ncudN0/g0.net] 分かりやすいように749みたいに書いたけど、747で普通に意味が通じるので、「ではなく」というとちょっと違う気がするかな。言葉って難しい。
754 名前:デフォルトの名無しさん mailto:sage [2025/11/16(日) 01:00:07.67 ID:oagsDxeg0.net] こういう人が仕様書読んで実装すると思うとこわい
755 名前:デフォルトの名無しさん [2025/11/16(日) 13:18:16.47 ID:0LN83zrSa.net] 横からだけど >>747 で充分判る >>748 は本当に日本人か?
756 名前:デフォルトの名無しさん mailto:sage [2025/11/16(日) 13:32:50.84 ID:Xh/GBEYv0.net] C++ばっかりやっとるからだよ 日本語を使え
757 名前:デフォルトの名無しさん [2025/11/16(日) 16:38:31.73 ID:r6khXsKc0.net] >>755 >748だけど日本人だよ。 >747日本語の文法としておかしいと思うんだが分かるんか…。 こっちが年食ったんかなぁ…。
758 名前:デフォルトの名無しさん mailto:sage [2025/11/16(日) 16:49:19.65 ID:D8AV/AUw0.net] あんたは機能的非識字なんでしょ 歳とか関係ないって
759 名前:デフォルトの名無しさん [2025/11/16(日) 18:20:15.84 ID:fnmgx6dT0.net] 747は、日本語の文法としておかしなところは別にないけれども、748のような読み方も許すという点で多義的な文にはなっているかな。 「C++より〜ように」という前半の文脈があるので748のような受け取り方はしない方が普通だと思うが、文法的には748のような読み方も一応可能だろう。 「使用可能(ということ)で良かった」としたら、完全に一義的になっているとまでは言えないまでも、多少ニュアンスは明確になっているかな。そうでもないか。
760 名前:デフォルトの名無しさん mailto:sage [2025/11/16(日) 19:06:28.66 ID:B8gkzotY0.net] >>757 文字なんでニュアンスが伝わりづらいだけだよ 「この前の件だけど、両方出来るようになったよ」 「他と同じように片方のみで良かったと思うよ」 まあ誤解を与えない書き方とすると 「他と同じように片方のみで良かったのにと思うよ」 って感じで「のに」をいれた方が残念がっている様子が伝わってくるよね
761 名前:デフォルトの名無しさん [2025/11/17(月) 09:06:44.31 ID:g7E0m0EQ0.net] C++はよく分からないので、cpprefjpにはいつもお世話になっているんだけど、生文字列リテラルのところにある「改行が入力された場合、改行の制御文字 '\n' に変換される」というのは説明として正確なのかな。 raw文字列リテラルのところの規格にはそれっぽいことは書いていないように思うし、改行文字は通常の文字としてそのままraw文字列リテラルに含められるだけであって、別に「変換」とかはされていないんじゃないかと思うんだけど。
762 名前:はちみつ餃子 mailto:sage [2025/11/17(月) 10:18:46.23 ID:DdlSQj440.net] >>761 '\n' に変換するという説明は誤りだと私も思う。 規格内の例中では \n と同等というような説明はあるのでこれを変換と誤解したのかも? https://timsong-cpp.github.io/cppwp/n4950/lex.string#5
763 名前:はちみつ餃子 mailto:sage [2025/11/17(月) 10:27:40.74 ID:DdlSQj440.net] 余談だけど生文字列リテラルの扱いにはちょっと変な特別扱いがある。 C++ では処理の初期段階で行を連結 (改行を削除) してしまうことになっていて、その時点では各改行が生文字列リテラルの中なのかどうか認識してない。 https://timsong-cpp.github.io/cppwp/n4950/lex#phases-1.2 後でトークンを分割するときになって生文字列リテラルを認識したらその範囲では連結を「取り消す」という処理が入る。 https://timsong-cpp.github.io/cppwp/n4950/lex#pptoken-3.1 結果としては改行はそのまま含まれるだけなんだけど、理屈としては色々な操作 (変換?) はされてる。 ただ、これは C++ の言語の解釈の話であって処理系の実装方法ではない。 つまり結果が同じであれば実装方法は問わないので連結してから取り消すのではなく連結の例外にしてもかまわないし、 生文字列リテラルを普通の文字列リテラルに変換するような手法もあるのかもしれない。
764 名前:デフォルトの名無しさん mailto:sage [2025/11/17(月) 20:16:57.16 ID:3c799E+W0.net] >>761 gccにCRLF改行のソースコードを食わせてもLF(\n)だけになったので変換はされてるんじゃないか 他のコンパイラの動作はしらね
765 名前:デフォルトの名無しさん [2025/11/18(火) 02:43:23.41 ID:oTdu6LNz0.net] >>763 削除されるのは「\(改行)」(Pythonとかでは明示的な行継続と言われているやつ)みたいなやつだけで、(\ に後続しない)単なる改行はwhitespace文字として扱われるだけかと思っていたんだけど。 >>764 改行をLFだけにする(正規化?)のは、raw文字列リテラルに限らない共通の処理なのでは。
766 名前:デフォルトの名無しさん mailto:sage [2025/11/18(火) 07:15:20.89 ID:cPKOUaFd0.net] 規格が決めてるのはソース中の論理的な「改行」の振る舞いであって、そのバイト表現は知ったこっちゃないって奴じゃないの 知らんけど
767 名前:はちみつ餃子 mailto:sage [2025/11/18(火) 10:05:52.54 ID:BySuHnsX0.net] >>766 従来はそうだったはずだけど C++23 からは Unicode (UTF-8) のコードポイントの並びで規定されていて、 CRLF が単一の改行に置き換えられる規則が明記されてる。 ただ、 Unicode 系以外の文字コードから処理系定義の規則で Unicode に適当にマッピングするようなのも認めているので実態はあまり変わらない。
768 名前:デフォルトの名無しさん [2025/11/18(火) 23:53:18.65 ID:+AochNn2a.net] >>764-765 termcapだかterminfoだかでゴニョゴニョ
769 名前:デフォルトの名無しさん mailto:sage [2025/11/19(水) 15:04:12.19 ID:HRoC/CWNM.net] >>768 関係ない