結局C++とRustってどっちが良いの?
■ このスレッドは過去ログ倉庫に格納されています
C++の色々配慮してめんどくさい感じは好きだけど、実務になったらメモリ安全性とか考えて今後Rustに変わっていくんかな?
このスレレベル高いね。 文系の俺にはちんぷんかんぷん。 雑魚はPHPでもしてるわ。 Rustはそのへんの話も明瞭で 「dyn」という予約語キーワードが出てきたものだけがvtableを使う動的ディスパッチとなるよ >>772 のRustコードは「dyn」が全く出てこないので、vtableを使う動的ディスパッチは一切無し、とわかる仕組み >>800 レベル高すぎてディスパッチが動的かどうかすらわからないからなwww 静的にディスパッチできたらいいのか、動的にディスパッチしたいのか。なんていうかgdgd ww >>800 ここは「朝から暇なおじさんの学習日記」だからある意味レベル高い。 >>801 を読んで思い出しましたが、 C++では動的ディスパッチが発生する条件のひとつとして、「virtual指定子付きメンバ関数の呼び出しである」という条件があります >>781 のコードにはvirtualがまったく存在しないため、動的ディスパッチが発生しないことが分かります >>789 のようにアセンブリでvtableの生成を確認するよりも、こちらのほうがより簡単な確認方法でした 誤った情報をお伝えしてしまい、大変申し訳ございませんでした ちゃんと検索したらなんかもうなんでもできそうなパターンマッチライブラリあった そうだよな、ないわけないよな https://github.com/BowenFu/matchit.cpp >>801 アホか? 静的ディスパッチとはコンパイル時に呼び出す関数が決定されることだよ match使ったら動的ディスパッチ >>807 Rustのenumのmatchはenumのインデックスで分岐してるだけ C++のvariantのvisitがvariantのインデックスで分岐してるだけなのと同じ どちらも動的ディスパッチはしていない 条件分岐は動的ディスパッチという 実行時ディスパッチと言った方が意味分かるかな? 動的ディスパッチというのは インデックスによる条件分岐 仮想関数によるディスパッチを含む広い概念です Rustも関数のオーバーロードくらいあるだろ? コンパイル段階でどの関数が呼ばれるかディスパッチされる これが静的ディスパッチ(の1つ) >>809 嘘つき 条件分岐つまりif文があれば動的ディスパッチだと主張するのか? 全てのプログラムが動的ディスパッチをしていることになるぞ >>812 >条件分岐つまりif文があれば動的ディスパッチだと主張するのか? その通り if文でどの関数を呼ぶか決めてるのであれば それは動的ディスパッチと言う これらはvtableを使うわけでもないし動的ディスパッチじゃないでしょ > Rustのenumのmatchはenumのインデックスで分岐してるだけ > C++のvariantのvisitがvariantのインデックスで分岐してるだけなのと同じ > どちらも動的ディスパッチはしていない >>814 >>772 >fn enum_pattern(shape: Shape) { > match shape { > Shape::Circle(r) => println!("半径{r}の円です"), > Shape::Rectangle(w, h) if w == h => println!("長さ{w}の正方形です"), > Shape::Rectangle(w, h) => println!("幅{w}高さ{h}の長方形です"), > x => println!("その他の図形{x:?}です"), > } >} ShapeがCircleなのかw == hであるRectangle(w, h)なのかそれ以外のRectangleなのか それともそれらに該当しないのかは実行時に決めているので 動的ディスパッチだよ 一方で >>785 >namespace Shape { > struct Circle {uint32_t r;}; > struct Rectangle {uint32_t w; uint32_t h;}; > struct Parallelogram {uint32_t ui0; uint32_t ui1;}; > template <typename T> void function (ostream &os, const T &p) {} > void function (ostream &os, const Circle &p) {} > void function (ostream &os, const Rectangle &p) {} >} 上記のどのfunctionが呼ばれるかは型に基づいてコンパイル時に選択される これが静的ディスパッチ じゃあ>>789 のC++コードは動的ディスパッチなの? vtableは無いしstd::visitでvariantのindex()値を見て実行時に分岐してるだけだから静的ディスパッチだと書かれているけど ID:wHEiYRW7は一つのIDを一貫して使ってるのに対し それにあほなレスつけて食って掛かってるほうはIDコロコロなんで 草も生えない毎度毎度のいつもの百年前から一生やってるrustスレ名物展開 >>817 Shapeが何かによって決めてるのは実行時なので 動的ディスパッチだよ ID:wHEiYRW7 >>809 がバカすぎる ID:7YA3tv0i氏の>>795 の説明を読もうぜ >>819 variantまで動的ディスパッチ扱いにするのはおかしいよ virtual関数をvtable経由で呼ぶのが動的ディスパッチじゃないかな >>795 >また、「実行時にデータ内容に応じて分岐することを動的ディスパッチと言う」という定義には明らかな問題があります >それは、この定義ではmatchやifなど通常の制御構造も動的ディスパッチに当てはまってしまうということです 何だそりゃ?w この説明の方が明らかにおかしい 他人に教えてもらったばっかりの内容で偉そうにしてんじゃねえ >>821 variantは良く知らんがShapeが実際には CircleかRectangleかParallelogramかを 実行時に判断しているので動的ディスパッチだよ >>816 との差は分かるでしょ? 分からんか? C++のvariantやRustのenumの値で条件分岐することを動的ディスパッチというのは無理があるんじゃないかな それはif文を使ったら動的ディスパッチと言ってるようなもの まだやってら どっちが来てもおっけーなようにtemplate<>が書けるのがC++のOOPだろ 無駄な議論 Rustもそんな感じだろ?w どっちも動的ディスパッチじゃなくね コンパイル後のenum_patternにCircleでもRectangleでもRectangleでもなく HogeAngleぶち込んでもディスパッチしてくれるのが動的じゃないの? >>825 >それはif文を使ったら動的ディスパッチと言ってるようなもの >>772 はShapeが何かはコンパイル時には決まりません >>789 もShapeが何かはコンパイル時には決まりません matchやifを使うということは実行時に決めていることを意味しているので動的ディスパッチです templateを駆使してコンパイル時に決定できる条件分岐を書けば 静的ディスパッチできるかもしれません 静的じゃないものは動的でいいと思うけど ディスパッチディスパッチ言ってんのは関数だけを前提にしたほうがいいんじゃない? match についてはもとの?ディスパッチ話から分離させたほうがいいかも? それとも元々matchの話なんだっけ? 最初の方読んでないけど 今まで関数かメソッド以外の文脈でディスパッチとか聞いたことなかったわ個人的に C++erは、書いたコードがディスパッチになるかは常に気にしてるからね(諸派あり そこを雑に書くと、ぶん殴られたりするからw だから、Rustの、書けばsafeになるってのは、欲しいんだなあ 生成コードに集中できる 百科事典で調べてみた >> https://www.weblio.jp/content/%E5%8B%95%E7%9A%84%E3%83%87%E3%82%A3%E3%82%B9%E3%83%91%E3%83%83%E3%83%81%E3%81%AE%E4%BE%8B >> C++では以下のように仮想関数を派生クラスにてオーバーライドすることで、 >> 実際に呼び出される関数の実体をオブジェクトの型に応じて実行時に選択することができる。 >> これを動的ディスパッチと呼ぶ。 この定義だとC++のvariant/visitでの分岐やRustのenum/matchでの分岐は動的ディスパッチではないな 一方でC++のvirtual関数やRustのdynトレイトは動的ディスパッチとなる >>832 >> https://www.weblio.jp/content/%E5%8B%95%E7%9A%84%E3%83%87%E3%82%A3%E3%82%B9%E3%83%91%E3%83%83%E3%83%81%E3%81%AE%E4%BE%8B >> C++では以下のように仮想関数を派生クラスにてオーバーライドすることで、 >> 実際に呼び出される関数の実体をオブジェクトの型に応じて実行時に選択することができる。 >> これを動的ディスパッチと呼ぶ。 これは動的ディスパッチの1つで 実行時に条件分岐して呼ぶ関数を決めるのも動的ディスパッチと呼ぶ 仮想関数によるディスパッチより動的ディスパッチの方が広い概念だよ 横からすみません Rustで日常茶飯事のこのパターンは動的ディスパッチですか? let output = match input { Some(input) => foo(input), None => Default::default(), }; >>827 何があれば「実践的」と言えるかの条件と、そもそも何のサンプルが欲しいのか、を明確にしないと誰も何も出せないよ >>772 はジャンプテーブルがないから動的ディスパッチじゃない >>834 それも動的ディスパッチじゃない >>833 が主張する『実行時に条件分岐して呼ぶ関数を決めるのも動的ディスパッチと呼ぶ』は無理があるんだよ >>838 俺はRust分からんのだけど これinputがSome(input)に適合するかしないかを 実行時に判断しているんやろ? だとしたら動的ディスパッチだよ C++のtemplateみたいに上記をコンパイル時に判断して 例えばSome(input)に適合するからDefault::default()を コールするコードが生成されないようなら静的ディスパッチ >>836 いま話題にしてる もとになった、パタンマッチングを上手く使ってる実例 なるほどこれはパタンマッチングがあってこそ、キマってるねっていうか というか>>789 の「静的ディスパッチ」もよく考えたら誤用だったわ https://en.wikipedia.org/wiki/Static_dispatch Rustならtrait bound付きgenerics内のtrait method呼び出しのことで良さそうだけど C++なら……ちょっとこのwikipediaの定義もなぜかオーバーロードに限定しててビミョ〜 これはRust以外の文脈では合意された定義無い気がする 静的か動的かはお互い認識にズレ無いと思うんよね でも「ディスパッチ」って言うとき 言語機能として用意されてる関数オーバーロードやvirtual使ったポリモとか 動的静的に関わらずまぁそこまではディスパッチなんだけど matchの結果やifの結果となってくるとそれって 言語の機能というより、言語の機能の機能ってことになってて 一気にぼんや〜りとしてくるんで一人一人にズレが生じるよね 1.どの振る舞いをするかがコンパイル時に選択される構造 2.どの振る舞いをするかが動的に選択される構造 3.振る舞いが追加されても動的に選択できる構造 パターンマッチは振る舞いの選択の話だから2 ポリモーフィズムを語る上での動的ディスパッチは3 2を動的ディスパッチと呼ぶかどうか >>839 実行時にならないとSomeかNoneかわからないからプログラムを組むんですよ コンパイル時点で決まっていたらプログラムを組む意味がありません そしてプログラムを組めば必ずどこかに条件分岐があります それを動的ディスパッチとは言わないと思うんです >>840 C++?Rust?どっち? てかやっぱり基準が曖昧だけど、何かしら有名OSSのソースでも出せばいいの? >>841 >This contrasts with dynamic dispatch, which is based on runtime information > (such as vtable pointers and other forms of run time type information). そこにdynamic dispatchを説明する一文があって2行目()内の and以下に書かれているのがまさにifやmatchで評価していること >>845 明らかにそいつは周回遅れのド素人なので アナタ以外のみんなは単に無視してるようですよw 時間の無駄はおすすめしません >>846 type informationとありますね SomeもNoneも型ではありませんから >>834 は動的ディスパッチではないということになります Rustのenumによるmatchでの分岐は動的ディスパッチではないということでよろしいでしょうか? >>845 RustのOSSで >>847 よく言われるよ >>844 条件により振る舞いを変えること一般をディスパッチと呼ぶ 例えば>>785 でmain内でfunction (cout, circle);とfunction (cout, parallelogram);では 呼ばれる関数が変わり振る舞いが変わるんだけど これはコンパイル時に選択されます これを静的ディスパッチと呼びます 一方で834のmatchによる分岐は静的には決まらないので 静的ディスパッチに対して動的ディスパッチと呼びます >>846 それはjsとかRubyとかPythonではvtableじゃなくてハッシュテーブルを使ってメソッド呼び出ししてるって意味ですよ >>848 それは字面に囚われていて本旨を捉えていないと思うよ 例えば憲法第二十四条第一項は「婚姻は、両性の合意のみに基いて成立し」を 根拠にして同性婚は憲法違反と主張するようなもの >>850 示してくださった定義>>846 には ランタイム型情報に基づく場合が動的ディスパッチですよね しかしSomeもNoneも静的に決まっているenum Option型の中の話ですからランタイム型情報は使っていません したがってenumのmatchは動的ディスパッチに該当する要素が全くないため、動的ディスパッチではありません、という結論になります >>854 これだったら、yylvalでいいよね。。 もうちょっとない? >>853 コンパイル時にその後の振る舞いが決まるかどうかに興味があって それを動的か静的かと呼んで議論しているんじゃないのかな? >>855 これパーサじゃないです……yylvalでよくないです…… イチャモン付けたいだけならもう返しません…… 結局まとめるとこうかな? 静的ディスパッチ ← 静的に型情報が決まる場合にコンパイル時に呼び出しメソッドが確定すること 動的ディスパッチ ← 動的に型情報が決まる場合に実行時に呼び出しメソッドが確定すること Rustのmatch文でのenumの分岐は静的に型情報は確定しているけど呼び出しメソッドを決めるわけではないので静的ディスパッチではない Rustのmatch文でのenumの分岐は静的に型情報は確定しているため動的に型情報が決まる動的ディスパッチとは無縁 つまりRustのmatch文でのenumの分岐はどちらのディスパッチでもなく一つの型の中の値による条件分岐にすぎない >>858 型情報による条件分岐に限らず値による条件分岐も動的ディスパッチだよ なぜならC++の場合typeid演算子で取ったtypeinfoオブジェクトで条件分岐したら それは型情報なのか値なのか?両者に差はないから >>859 -両者に差はないから +両者を分ける意味はないから >>859 この場合のディスパッチとは型情報に基づいて呼び出しメソッドを決定すること それが静的に決まれば静的ディスパッチ そして動的に決まれば動的ディスパッチ 型情報に基づかなければ単なる昔からの条件分岐プログラム typeidで得られるのは型情報なのでtypeidに基づくならば動的ディスパッチに該当する 条件分岐は条件分岐でしかない ディスパッチは条件分岐を用いずに振る舞いを切り替えること >>861 typeinfoの実装見てみ 環境違ってもそんなに変わらんと思うから >>864 ちゃうやろ 比較で分岐するか 次の振る舞いがあるところに飛ぶか >>863 型情報を整数値で表すのは当たり前だけど それは型情報ではない普通のデータの整数値の分岐とは話が全く違う 型情報によって呼び出すメソッドが変わるからそれを決定することをディスパッチと呼ぶ その型情報が静的に決まるか動的にきまるかの違いのみ typeidを使っているならば型情報が動的に決まっているのだから動的ディスパッチ >>834 そもそもそれをディスパッチと普通呼ぶ? やってることはvtable使った動的ディスパッチも似たようなものだから 動的ディスパッチの一種とすることにそこまで違和感はないけど 広く浸透してる定義ではないよね 名称はともかくmatchの分岐はコンパイル時に決まらず 実行時に比較のオーバヘッドがある認識は共通しているので 何も対立はないはず C++のmatchの話にもどしましょ >>868 >型情報を整数値で表すのは当たり前だけど >それは型情報ではない普通のデータの整数値の分岐とは話が全く違う わかんねーよw もういいよ まず>>846 のstatic dispatchのページからとって来た文章をdynamic dispatchの「定義」として参照するのが間違い こりゃすでにdynamic dispatchが定義された前提の上で、static dispatchと異なる点を書いているだけだよ 自分の思い込みを肯定するために都合良く文章を解釈してしまうのは人間やりがちだけどね >>867 ディスパッチは条件により分岐しない 渡された振る舞いを実行するだけ 例えば>>841 のサイトのspeakに分岐処理は無いでしょ 話は簡単 まず前提「オーバーロードにより型が決まらないと呼び出す実メソッドが決まらない」 つまり「型情報が決まると呼び出すメソッドが決まる」 この決定のことをディスパッチと呼ぶ 静的に型情報が決まる場合は静的ディスパッチが可能 動的に型情報が決まる場合は動的ディスパッチとなる 型情報と関係ない話はどちらでもない >>874 > まず前提「オーバーロードにより型が決まらないと呼び出す実メソッドが決まらない」 > つまり「型情報が決まると呼び出すメソッドが決まる」 > この決定のことをディスパッチと呼ぶ ここだけ読むとオーバーロード解決に聞こえるねw https://ja.cppreference.com/w/cpp/language/overload_resolution Visitorパターン=多重ディスパッチ説があったからそれが元凶だろう 複数のメンバー関数から一つ選ぶのもディスパッチ だから多重という 動的ディスパッチや静的ディスパッチは 何をディスパッチするのか考えなよ Rustは普通に書くだけでこのスレで言うところの静的ディスパッチとなりコンパイル時点で単相化されて速い 実行時にしか型が判明しない場合に対してはdyn指定による動的ディスパッチが可能でvtableが使われる vtableを避けたいならばenumに包むことで直和型として収容して扱うこともできる vtableの持ち方がRustとC++では違うんだよね >>877 SpringやFluxのディスパッチャーだったり Grand Central Dispatchだったり 何に対しても使える用語だから 区別できてない人もいるんだろう C++では、クラスが仮想関数を持つ場合、そのクラスのインスタンスに対して仮想関数テーブルが作成される。 仮想関数テーブルには、仮想関数へのポインタが含まれインスタンスに対して仮想関数が呼び出されるたびに vtableを参照して適切な関数が呼び出される。 Rustでは動的ディスパッチを実現するためにトレイトオブジェクトが使用される。 トレイトオブジェクトには、traitオブジェクトが実装する各メソッドに対応するポインタのリストが含まれていて インスタンスに対してメソッドが呼び出されるたびに、トレイトオブジェクトが参照され 適切なポインタが見つかるまでリストを検索し適切な関数が呼び出される。 結果は同じ。 >>882 詳細の説明がいろいろおかしいと思うけどどこソースなの? >>882 クラスとインスタンスの関係を理解してないな C++の説明もRustの説明も同じように間違ってる おまえオブジェクト指向を理解してなさそうと言われてたやつだろ >>882 うーむひどいな とりあえずRustについて、この部分の間違いはあまりにひどい > traitオブジェクトが実装する各メソッドに対応するポインタのリストが含まれていて > 適切なポインタが見つかるまでリストを検索し適切な関数が呼び出される。 Rustは常にメソッドが静的に一意に確定するため、動的ディスパッチでも適切なポインタが見つかるまでリストを検索する必要がない Rustはメソッド名が衝突する場合、まず自分の定義優先で確定、なくてトレイト間に衝突がなければ確定、衝突があればエラーだが、トレイト名を指定することでどのトレイトのメソッドでも常に利用可能 つまりRustではメソッド呼び出しが自分のメソッドかどのトレイトのメソッドかが静的に一意に確定する 静的ポリモーフィズムとして使われるときは、必要とする最小限のトレイトを列挙(=トレイト境界)するため、メソッドの衝突の可能性は通常時よりも減ったり無くなったりする いずれにせよ上述したようにメソッドは静的に一意に定まるため、静的ディスパッチでは単相化(モノモーフィゼーション)されてコンパイルされる 動的ポリモーフィズムとして使われるときは、現在の仕様では指定できるトレイトは(auto traitを除き)一つのみに限定されている ただし必要とするトレイトを列挙(=トレイト境界)したダミーなトレイトを任意に作ることも可能なため、事実上は複数のトレイトを指定できるのと同じ 指定トレイトが一つに限定されているということは、(そのトレイト境界を含めた)トレイト群すべてのメソッドを静的に一斉に把握できることを意味する つまりRustのvtableはその指定トレイト一つのみに定まり、その親や祖先のvtableを辿る必要がなく、呼び出すメソッドは静的に確定してインデックス値となっているため、動的ディスパッチでも高速にメソッドを呼び出せる 間違ったことを書いてる人は完全に悪いけど、内容があれば議論のネタになるからまだマシ それに対して間違ってる!とか、虚言!とかだけ言う連中は全く役に立たないから無視してよい なぜなら、正しいことが書かれている場合でも、間違ってる!とか適当なこと言ったりするだけの連中も多いため >>886 > つまりRustのvtableはその指定トレイト一つのみに定まり、その親や祖先のvtableを辿る必要がなく C++も同じです > 動的ディスパッチでも高速にメソッドを呼び出せる 何と比較して?静的に比べりゃどうやったって遅いしそこにC++との差はないはずだし 不合格 >>887 テキトーかどうかの検証のために、出典を貼っていただけるとみんなが助かります やるつもりが無いなら頃合いを見てマサカリを投げさせていただきます >>888 そういう意味のない言いがかりはやめとけ 元の>>882 が正しくないこと「適切なポインタが見つかるまでリストを検索」と書いているので、 それに対して正しいこと「親や祖先のvtableを辿る必要がなく、動的ディスパッチでも高速にメソッドを呼び出せる」と書いた そこで「静的に比べりゃどうやったって遅い」と頓珍漢なことを言い出すのは理解力のない証拠 これ以上は相手にしない OpenCV-rs ってもうメンテされてないんか? gdgd なんだが >動的ディスパッチ もしかして 遅延バインディング おじオジ言ってる人は頭がおかしいと他のスレで習ったけどここでもそうなの? てかよく読んでみれば>>882 自体は「適切なポインタが見つかるまでリストを検索」としか書いてなくて 具体的にどういうリストなのかの説明は一切無し なのになぜか>>886 は「親や祖先のvtableを辿る」と、親子関係でリストができる?のを何故か仮定している そういうことだよねw >>887 「最初から間違ってると思ってた」と事後に言うと、本当に最初からだったのかが真偽不明になるから 内容がなくても時刻を記録するだけで意味があるんだよ 祖先のテーブルをたどっていく実装や言語あるよ 特にJavaScriptはメソッドを後から生やせるから大変だった >>896 とりあえず、プライドは高いということは分かった >>887 どう見ても君が間違ってる本人じゃん なぜバレないと思ったの? ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.4 2024/05/19 Walang Kapalit ★ | Donguri System Team 5ちゃんねる