結局C++とRustってどっちが良いの?

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2023/02/25(土) 09:49:46.74ID:VRyB88xR
C++の色々配慮してめんどくさい感じは好きだけど、実務になったらメモリ安全性とか考えて今後Rustに変わっていくんかな?
2023/03/24(金) 02:07:17.26ID:GMecybVR
>>488
>>489
サンクス
なんかスマートポインタ推されてるからリアロケーション追跡するポインタとか出来てるのかと思った
2023/03/24(金) 02:12:19.33ID:7trvtA/S
>>487
C++のスマポは使い方をミスったらおしまいで実際に問題を起こし続けている欠陥品
null安全か否かは言語仕様で決まりもちろん静的に防げる
当然C++はnull安全な言語ではない

>>488
vectorの自動メモリ再配置によるダングリング発生がうっかりミスで容易に発生するC++は欠陥言語
492デフォルトの名無しさん
垢版 |
2023/03/24(金) 02:30:27.68ID:STP4y0mB
>>491
>C++のスマポは使い方をミスったらおしまいで実際に問題を起こし続けている欠陥品
どういうミスかな? 書いてみ

>null安全か否かは言語仕様で決まりもちろん静的に防げる
これもどういうケースを言っているのか分からんので書いてみて

>vectorの自動メモリ再配置によるダングリング発生がうっかりミスで容易に発生するC++は欠陥言語
連続するアドレスに領域を取ることが保証されているコンテナはRustにはないのかな?
C++はもちろんメモリ再配置しない(領域が連続しない)コンテナを選択できる

反論したいので具体的に書いてね
無理かもしれんがもし書けるならC++のソースで例示してね
2023/03/24(金) 02:43:13.61ID:Qymt7I/N
ちゃんと書けば動く、は言語として甘え
C++は一刻も早く進化すべきだ
2023/03/24(金) 02:54:47.10ID:STP4y0mB
具体的にね
2023/03/24(金) 03:22:24.82ID:pHWoHRbv
>>491
欠陥言語というか他の言語たちと比べればCやC++はわずかなミスで危険なことになるから大きなマイナスかもしれないけど
省メモリで高速という他の言語では得られない巨大なプラスがあるからC++は必須の存在だったのよ
今はその巨大なプラスがありつつマイナスのないRustが登場したからC++は価値がなくなり役目を終えたけどね
496デフォルトの名無しさん
垢版 |
2023/03/24(金) 04:28:25.21ID:F7DMT464
>>495
役目を終えたならC++で書かれた全てのソフトウェアがRustになってもおかしくないけど全くそうじゃないよな?
2023/03/24(金) 04:38:49.00ID:pHWoHRbv
>>496
既存システムの書き直しは時間と費用がかかるからやるとしても少しずつでしょ
多くのシステムは大規模更新時の機会にでしょ
新規に登場したシステムはRust製になっていってますね
498デフォルトの名無しさん
垢版 |
2023/03/24(金) 04:46:18.91ID:F7DMT464
>>497
ならないと思うけどね
まぁ何言っても無駄かw
499デフォルトの名無しさん
垢版 |
2023/03/24(金) 05:43:54.98ID:pnAyfShU
そもそもC++ってCと比較しても脆弱性が下がる気がする。
なんか初心者泣かせのトラップが多すぎるんだよな。
2023/03/24(金) 05:50:11.50ID:G7wXKrBj
>>460
ありがとうございました
501デフォルトの名無しさん
垢版 |
2023/03/24(金) 05:58:04.68ID:G7wXKrBj
>>484
GCって禿のことだったんですね
2023/03/24(金) 06:06:32.31ID:G7wXKrBj
>>499
>初心者泣かせのトラップ

むしろ知ったかがドツボに嵌る
2023/03/24(金) 10:43:05.72ID:qDyrJPYZ
>>492
rustのvectorは再配置される可能性がある操作時は他からの参照がないことがコンパイル時に保証されるので連続領域でも問題ないよ
2023/03/24(金) 11:32:45.65ID:STP4y0mB
>>503
ほう! Rustはよう知らんのでC++で聞いて申し訳ないが
以下コメントの部分(1)と(2)は
Rustで相当するコードを書いたらコンパイルが通らないということかな?
#include <iostream>
#include <vector>
#define DOUT(arg) std::cout << #arg": " << arg << '\n';
int main () {
std::vector <int> v;
v.reserve (1);
DOUT (v.capacity ());
v.push_back (10); // (1) Rustで許容 or エラー?
auto itr {v.begin ()};
DOUT (*itr);
v.push_back (11); // (2) Rustで許容 or エラー?
DOUT (v.capacity ());
// DOUT (*itr); // dangerous
return 0;
}
$ ./a.out
v.capacity (): 1
*itr: 10
v.capacity (): 2
2023/03/24(金) 12:12:50.87ID:yujZIUnP
>>504
(1)の段階では問題ないけど
(2)の段階ではitrとpush_backがコンフリクトするからコンパイルエラー
2023/03/24(金) 12:16:34.86ID:+nRUfXDq
>>504
当然エラーは起きない

fn main() {
let mut v = Vec::<i32>::new();
v.reserve_exact(1);
dbg!(v.capacity());
v.push(10);
let first = &v[0];
dbg!(*first);
v.push(11);
dbg!(v.capacity());
dbg!(v.len());
// dbg!(*first); // dangerousなこれを入れたときだけコンパイルエラー
}

[src/main.rs:4] v.capacity() = 1
[src/main.rs:7] *first = 10
[src/main.rs:9] v.capacity() = 4
[src/main.rs:10] v.len() = 2
2023/03/24(金) 12:23:09.85ID:STP4y0mB
>>505,506
どっちが正しいんだい?
2023/03/24(金) 12:23:39.80ID:xsjnwqf2
ああそれはそうね
2023/03/24(金) 12:24:51.09ID:xsjnwqf2
>>506が正しいよ
オレはdangerousがある前提で考えてたから
2023/03/24(金) 12:27:08.05ID:+nRUfXDq
(2)の段階より前に参照や可変参照があっても
(2)の段階より後に使われなければ
(2)の段階より前までにそれらの参照のスコープが自動的に終わる(=ライフタイムが尽きる)
したがってコンフリクトは起きない

一方でもしdangerousの部分のコードがある場合は
(2)の段階より後に使われているため
コンフリクトが起きるためコンパイルエラー
2023/03/24(金) 12:31:23.73ID:STP4y0mB
有難う
reserve_exactの引数が定数1のときには
最終行のdangerousを入れるとコンパイルエラーを出すということだが
reserve_exactの引数が変数で実行時にしか定まらんときは
コンパイルエラーにできないと思うんだが危険じゃね?
2023/03/24(金) 12:35:02.24ID:STP4y0mB
>>510
なるほどー
Rustってデストラクタはいつ呼ばれるの?
ライフタイムの終わり? あるいはデストラクタはない?
2023/03/24(金) 12:48:05.77ID:+nRUfXDq
>>511
指定サイズは一切関係ない
データ競合が起きないようにmultiple readers or single writerの鉄則に基づく
pushすなわち書き換えたいならば他にreader(参照)もwriter(可変参照)も生きていてはいけない

>>512
所有権を持っている変数がスコープから外れると
所有者が居なくなりデストラクタ相当が呼ばれて自動的に安全にメモリ解放される
2023/03/24(金) 13:14:43.88ID:STP4y0mB
>>513
>>>511
>指定サイズは一切関係ない
>データ競合が起きないようにmultiple readers or single writerの鉄則に基づく
>pushすなわち書き換えたいならば他にreader(参照)もwriter(可変参照)も生きていてはいけない
pushしたあとはたとえcapacityの範囲内で再配置が行われてないとしても
参照を取得し直すってことかな?
2023/03/24(金) 13:21:48.64ID:STP4y0mB
>>513
Rustのスコープ=ライフタイムとすると
デストラクタが呼ばれるタイミングが分かり難くないかい?
ちょっとソースをいじって後ろの方でインスタンスを触ると
呼ばれるデストラクタが呼ばれるタイミングも
自動的に後ろになるということかな?
C++ほどデストラクタに処理を書かないのかな?
2023/03/24(金) 13:23:02.73ID:+nRUfXDq
>>514
再配置だけでなく値が書き換わる可能性もある
それらの可能性やそれらの操作を跨いで参照を保持してはいけない
逆に言えば参照を持ち続けることができているならば指している値が変わらないことが保証される
これはバグを防ぐとともにコンパイラによる最適化の余地も広げ高速化にも寄与する
2023/03/24(金) 13:31:39.50ID:STP4y0mB
>>516
なるほどね
まぁ俺は再配置が起こらないと分かるところで
いちいち参照は取り直したくはないな

Rustのデストラクタが呼ばれるタイミングは
インスタンスのライフタイムで変わりうるということで良い?
2023/03/24(金) 13:32:37.18ID:+nRUfXDq
>>515
デストラクタが呼ばれるのはその変数の「ブロックスコープ」のブロックを出るタイミングだから一定している
2023/03/24(金) 13:37:44.31ID:STP4y0mB
ブロックスコープって多分C++のスコープと同じだよね?
ライフタイムとまた違うのかな? 複雑だなぁ
2023/03/24(金) 13:53:25.98ID:+nRUfXDq
>>519
誤解をしている
ブロックの途中で打ち切られる可能性があるのは参照のライフタイム
そして参照にはデストラクタはない

一方で値そのもののライフタイムつまり所有権が尽きるのは常にブロックスコープに従う
デストラクタが存在すればブロックを抜けるタイミングで呼ばれる
その後でメモリ解放が自動的に行われる
2023/03/24(金) 13:55:42.43ID:GMecybVR
デストラクタは所有してる変数のブロックを抜けるまでに呼ばれることが保証されてるけど
正確なタイミングはコンパイラが決めてるから予測はできない
例えば何かを解放しないと以降で競合が生じる場合はブロックの途中で解放されることもある

ただ
A()
B(&A)
みたいにBがAを参照してるような状況だとBが消えるまでAを動かせないから
結果的にC++と同じように逆順で解放されることになる

ライフタイム周りはコンパイラが制約を満たせる処理順を見つけて裏で調整する感じだから
最初は戸惑うかもしれないね
2023/03/24(金) 14:00:41.09ID:+nRUfXDq
>>521
let _ = x; で棄てる以外に
ブロックの途中でデストラクタが呼ばれるケースあるっけ?
2023/03/24(金) 14:34:12.82ID:JpLx+uLR
>>520
それどこのスマポ
2023/03/24(金) 14:38:27.83ID:STP4y0mB
>>520,521
なるほどね
参照って読んでるのは>>506だとfirstのことかな?
参照の中にC++のstd::shared_ptrの挙動を内在させてるイメージを持った
Vecのアクセスにiteratorは使わないのかな?
2023/03/24(金) 14:55:23.36ID:+nRUfXDq
>>523
デストラクタにスマポもポインタも関係ない
Rustでは任意の自作型にデストラクタを実装できる
(ただしCopyを実装していないことが条件)

// 例えば整数i32型のみを持つ構造体Foo
struct Foo(i32);

impl Drop for Foo {
// デストラクタ実装
fn drop(&mut self) {
println!("drop: Foo({})", self.0);
}
}

fn main() {
let _x = Foo(123); // メインブロックを終えてからdropされる
{
let _x = Foo(456); // 内ブロックを終えてからdropされる
let _x = Foo(789); // 内ブロックを終えてからdropされる
println!("内ブロック終わり");
}
println!("メインブロック終わり");
}

【実行結果】
内ブロック終わり
drop: Foo(789)
drop: Foo(456)
メインブロック終わり
drop: Foo(123)
2023/03/24(金) 15:07:39.53ID:GMecybVR
>>522
すまん
ちょっと勘違いしてた
Dropあると明示的に捨てる必要あるな
2023/03/24(金) 15:07:52.15ID:+nRUfXDq
>>524
C++とRustはiteratorで指すものが微妙に異なるので要注意だがまずは折衷するとして
例えば
let mut v = vec![1, 2, 3];
for p in v.iter_mut() {
*p += 10;
}
これでイテレータを使って11,12,13
2023/03/24(金) 15:18:17.49ID:m8vHxf3R
>>521
Drop scopeがブロックとは限らないだけで予測できないわけではなくね?

>>525
let x = Foo(123).0 * 2;
とか
let mut x = Foo(124);
x = Foo(456);
とか
2023/03/24(金) 15:28:04.96ID:STP4y0mB
>>527
>>506の let first = &v[0]; の部分をイテレータに差し替えると
(記法は分からんが仮に let first = v.iter() かな?)
イテレータのライフタイムも参照の場合と変わらず
v.push(11);と最終行のdangerousを併存させると
capacityに関わらず問答無用にコンパイルエラーといことかな?
2023/03/24(金) 15:30:39.43ID:+nRUfXDq
>>528
変数が所有している値のデストラクタが呼ばれるのはブロックを抜けた直後だけど
変数が所有しない一時的な値や変数が所有しなくなる代入前の値などは
_へ棄てるのと同じくブロック途中でデストラクタが呼ばれるね
2023/03/24(金) 15:33:55.56ID:STP4y0mB
Rustってゴミ箱(_)があるんだなw
2023/03/24(金) 15:51:46.07ID:+nRUfXDq
>>529
もちろんイテレータは参照もしくは可変参照を持つ形となるのでsingle writer or multiple readersを満たす必要がある
それを満たせなければコンパイルエラーとなりデータ競合を防げる
2023/03/24(金) 15:55:15.22ID:+nRUfXDq
>>531
棄てるのは _ へ棄てなくてもいくらでも方法があり
例えばブロックを作れば
{
let _tmp = x;
}
これで_tmpへ値が移動してブロックを抜けるときに消える

他にも例えば以下の関数を定義して
fn 棄てる<T>(_tmp: T) {
// 何もなし
}
棄てる(x); とすればその関数へ値が移動して関数ブロックを抜けるときに消える
この棄てる関数は同じものがstd::mem::drop()に用意されているので意図をはっきりさせるためにはそれを使うことで可読性を持たせる
2023/03/24(金) 17:20:54.03ID:ENxn1p6S
>>530
細かいことだけど一時的な値は内部的に一時変数が所有してることになってて一時変数がDrop scopeを抜けていなくなるタイミングでデストラクタが実行される

let _ = Foo(123);やx = Foo(456);は代入によって値の所有者がいなくなるからそのタイミングですぐにデストラクタが実行される
2023/03/24(金) 20:26:32.48ID:STP4y0mB
>>533
こういうことだわな

#include <iostream>
using namespace std;

struct A {
A () {cout << "constructor\n";}
~A () {cout << "destructor\n";}
};

template <typename T> void drop (unique_ptr <T> &&p) {}

int main () {
auto x {make_unique <A> ()};
{
auto _tmp = move (x);
}
drop (move (x));
return 0;
}
2023/03/24(金) 21:50:27.51ID:VHzrsylr
dropバグっとるがな
2023/03/24(金) 21:51:22.79ID:STP4y0mB
ごめんごめん
538デフォルトの名無しさん
垢版 |
2023/03/25(土) 09:38:10.15ID:M09ogOTB
屁臭
2023/03/25(土) 20:06:44.69ID:sd+PB/iL
>>504
そういう小さい単純な例ならばdangerousなデータ競合であると自明だが
もっと複雑化して見逃す例が実際に起きてセキュリティの穴になる
2023/03/25(土) 20:52:44.35ID:c5G720p2
デバッガですぐに分かることなので
みょうちくりんな文法を新たに覚えようという動機にはならん
2023/03/25(土) 20:56:23.22ID:VVKoWVL2
不明な挙動があるのが発見されてない時点でもデバッガ使うの? 変なコード書いた本人に自覚がないから不具合として発現するのであって、正常に動くであろうと期待できてる時点でも?
時間の無駄では?
デバッガでわかるよりコンパイラでわかるなら圧倒的にそっちがベターでもあるし
2023/03/25(土) 20:58:28.17ID:c5G720p2
>>541
>不明な挙動があるのが発見されてない時点で
それはいくらなんでも無理だろw
2023/03/25(土) 20:59:37.07ID:tC35D9u3
>>540
デバッガなど実行時でないと検知できないショボいプログラミング言語は滅びそう
昔はC++は神の言語と信じていたけどアドバンテージを全て失ってしまったもの
2023/03/25(土) 21:03:00.33ID:c5G720p2
コンパイル時点でチェックが入るのはRustの利点だが
C/C++と乖離した文法を新たに覚えるというコストを払おうとは全く思わん
俺がRustを覚えるとしたらシステムコールがRustで書かれたOSを
使うことになったときだけ
当分ない
2023/03/25(土) 21:04:16.45ID:c5G720p2
>>543
でもLockFreeQueueをsafeで実装できないんでしょ?
2023/03/25(土) 21:10:35.10ID:c5G720p2
周りに使用を強制されるほどRustは普及していないので
Rust推しの諸君は自らRustを選択したのだろうけど
そんなにCでのメモリの扱い方に苦労したのかい?
Rust使う人はどちらかというと言語マニアの人達だと思ってたのだが?
2023/03/25(土) 21:14:16.97ID:tC35D9u3
>>545
そういうのはすべてsafeなインタフェイスでライブラリが作られてるから
LockFree{Queue,Stack,Map,Set,Chanel}すべてsafeなインタフェイスを用いてRustプログラミングできるよ
2023/03/25(土) 21:17:55.09ID:fB31q3I6
>>546
開発効率と可読性が圧倒的にRust>>>C++
Rustはコンパイル時点でミスが見つかるから効率良すぎ
可読性も大差でパターンマッチングの有無も大きい
2023/03/25(土) 21:18:50.17ID:c5G720p2
>>547
Rustでプログラミンしたいのではなくて
言語のウリとしている特徴の不備の一例として上げている
平たく言うと中途半端
2023/03/25(土) 21:23:11.57ID:tC35D9u3
>>549
すべてがunsafeなC++と違って
RustならLockFree{Queue,Stack,Map,Set,Chanel}をsafeなインタフェイスで使うことで自分の書くプログラムをsafeにできるよ
つまりRustコンパイラが書いたプログラムの安全性の保証をしてくれるよ
2023/03/25(土) 21:36:28.93ID:c5G720p2
>>550
Rustではsafeで全てを表現したいという目論見が破綻した
ということを指摘したい
これで良いかな?
更に良い言語が出るかもね
2023/03/25(土) 22:24:32.21ID:fB31q3I6
Rustは例えばVecすら中身はunsafeを使ったsafeなコードだらけだぞ
LockFreeも全く同様
unsafeを使ったsafeなコードで基本ライブラリを作成しsafeなインターフェースを提供できることがRustの最大の長所
それらを使うプログラムはsafeにすることが出来てコンパイル時点で各問題を排除できる
C++が敗北した理由である
2023/03/25(土) 22:28:23.02ID:c5G720p2
>>552
>Rustは例えばVecすら中身はunsafeを使ったsafeなコードだらけだぞ
だめだめじゃん
設計が間違ってるんだよ(というか無理だったんだよ)
2023/03/25(土) 23:00:19.34ID:tC35D9u3
プログラムすべてがunsafeなC++という失敗作を改善したことを設計ミスと言うのは理不尽ね
2023/03/25(土) 23:10:11.97ID:Ty/K+Fgo
>>543
C++大好きだが、神の言語とはちょっと違う希がす
2023/03/25(土) 23:25:09.01ID:c5G720p2
>>554
Rustは一過性の言語だと思うよ
C++はCを包含しているからそうそう消えないと思うが
Rustは後続の言語にオーバーライドされると思う
2023/03/25(土) 23:58:43.93ID:EBh7DtZR
現代語はコロコロ変わるが古文漢文は変化しないからそうそう消えない
理系のくせにそこに気付くとはえらいね
2023/03/26(日) 00:04:07.04ID:Vf0mvjFW
大手が採用するといったんだから当面生きてるでしょ
C/C++は進化はよ
2023/03/26(日) 00:38:53.03ID:04xno5ob
もう負けたんだよC++は
向こうの方が宣伝がうまかった
2023/03/26(日) 01:40:41.16ID:Vf0mvjFW
ついこないだまで、コルーチンだって書けなかっただろ
C++が「負け」てるのは、今に始まったことじゃない
キャッチアップしていってくれればいいんだよ
561デフォルトの名無しさん
垢版 |
2023/03/26(日) 08:24:37.76ID:4yCJuAuO
Nimは脳汁出るんだが
Rustからは出て来ない
::が邪魔しとるんかの
2023/03/26(日) 08:28:50.22ID:UQsado+I
>>543
Cは神言語だが
C++は神じゃないどころか
クソ言語だと言うのは当初から言われてた
563デフォルトの名無しさん
垢版 |
2023/03/26(日) 08:38:26.46ID:VUXuxgJn
C++はたとえリアルタイム性があっても、信頼性が求められる業務をしようとすると、どうしてもCで良いじゃんってレベルまでコーディングルールをガチガチに制約するからね。
2023/03/26(日) 08:42:34.83ID:faqu5Hbk
C++のメリットが完全に無くなったな
無理に挙げるとすれば過去のプログラムと過去のプログラマーくらいか
2023/03/26(日) 11:07:56.67ID:Vf0mvjFW
C++のメリットは自由度
自由が障壁になる用途ではメリットもクソもないw

C++で書きたいというニーズは当面残る
だからC++には進化してもらわないといけない
2023/03/26(日) 11:19:02.92ID:rT1rfVXr
GC無し言語でやりたいことは全部Rustでやって
C/C++には滅びて欲しい人間が増えてんだろ
プレーンCのコードぐらいRustにコンバート出来るんじゃね?
知らんけど
2023/03/26(日) 12:33:33.90ID:g6NQ2zfC
C++中毒な人が多いからね(俺含む
捨てろと言われても無理だねえw Rustを使わないとは一言もいってない

>>563
これまで、自由になりすぎたC++をいかに縛るかっていう試みはいくらもあったが、普及しなかった
ついにRustが答えを出した C++は「いや~負けましたね~」とかいいながら、その成果を吸収すればいい
2023/03/26(日) 13:03:12.58ID:BnHATVrm
自分で自由を縛ろうというインセンティブは働かないからね
何らかの外からの圧力がない限りなかなか増えないだろうね
キラープロダクトがあれば一気に普及するだろうけど
2023/03/26(日) 13:05:22.20ID:BnHATVrm
メモリ管理云々言ってる人もセールストークの受け売りで
自分でメモリ管理に苦労して「あ! Rustが解決法だ!」って
始めた人はいないだろうし
2023/03/26(日) 13:06:33.66ID:g6NQ2zfC
C++に依存すればするほど、これgdgdだ…ってのがわかってくるもんだけど、
どう縛るのが「正解」か、なかなか答えが出なかったんだよね
スマポどころか、ハンドルや参照カウントの概念が大昔からあったけど、決定打にならなかった
2023/03/26(日) 13:09:22.51ID:BnHATVrm
>>570
それは自然言語と同じで使う人のレベルによる
2023/03/26(日) 13:12:55.73ID:BnHATVrm
おまいらRedoxとかどうよ? GoogleのOSは一般の人は使えるの?
2023/03/26(日) 13:14:54.55ID:Lwno4Hfq
自由には需要のある自由と需要のない自由があってだな

どっちも供給されなければ胡散臭いとか偽善だとか
需要ってあなたの願望ですよね、とかいうのが自由にまつわる典型的な詭弁
2023/03/26(日) 13:19:57.22ID:BnHATVrm
需要あるから>>567の言うように
「自由になりすぎたC++をいかに縛るかっていう試みは
いくらもあったが、普及しなかった」のでは?
Rustもこのままだとone of themだろうけど
2023/03/26(日) 14:41:00.96ID:g6NQ2zfC
規格となるに足る、縛り(の規格)の決定打がなかった
あーでもないこーでもないいって、混沌を放置したのはC++の落ち度
バイナリだって肥大化し放題だったしね Cに近いC++erは、忸怩たる思いで眺めてたものさ
2023/03/26(日) 14:50:08.58ID:EIuzoBSL
ここって情報古い?
https://maku77.github.io/rust/

あと
if let Ok(hoge) = fuga {
}
って本当に可読性良くなってると思ってる?(嫌味じゃなくてマジでRust推しの人の意見聴きたい)
2023/03/26(日) 14:57:31.39ID:BnHATVrm
>>575
は? C++はISOもJISも規格あるやろ?
Rustに規格あるの?
2023/03/26(日) 15:01:34.10ID:g6NQ2zfC
>>577
大手が採用するといったんだから、採用されるバージョンが、当面のデファクトスタンダードになる
それは規格といっていいよ そして規格は、管理下で進化する
2023/03/26(日) 15:09:14.63ID:BnHATVrm
ダメだこりゃ
普及はもしするとしても30年くらいは掛かりそう
2023/03/26(日) 15:58:38.13ID:LwxNksN7
どちらを習得すればセックスできますか
2023/03/26(日) 16:29:03.94ID:v5z9D7dt
>>576
Rustの if let でのenumパターンマッチングは、
まずRustのenumを理解する必要があるけど、例えば、

enum State {
StateA(i32),
StateB(i32),
StateC(i32, f32),
}

if let State::StateA(i) = x {
println!("StateA: {i}");
}

これをc++で書こうとするとこうなるのかな。

struct StateA { int i; };
struct StateB { int i; };
struct StateC { int i; float f; };
typedef std::variant<StateA, StateB, StateC> State;

if (std::holds_alternative<StateA>(x)) {
StateA& a = std::get<StateA>(x);
std::cout << "StateA: " << a.i << "\n";
}

この両者がたぶん同じ。
if let構文のおかげでRustは可読性が増していると思う。
582デフォルトの名無しさん
垢版 |
2023/03/26(日) 18:24:04.21ID:MldEMOwI
>>576
>if let Ok(hoge) = fuga {
>}
>って本当に可読性良くなってると思ってる?
ResultやOptionが複数ネストしていくと可読性が低いコードはどうしてもできるけど単純なやつは何の問題もないと思ってる

ちなみに何と比べてる?
2023/03/26(日) 23:06:22.21ID:zumLAqyb
>>581
C++は利便性のいい代数的データ型の導入に失敗したからしょうがない
さらにパターンマッチングの導入は未だに議論中のまま進みそうにない
結果としてそのような不便で分かりにくい記述をするしかない
2023/03/26(日) 23:24:54.44ID:Lwno4Hfq
C++にはswitchを使うなunionを使うなという縛りがあった
CとC++を意図的に隔離すれば縛りを無視できるから問題視されないが
2023/03/26(日) 23:35:48.82ID:BnHATVrm
何か問題でも?
2023/03/26(日) 23:51:37.40ID:Lwno4Hfq
if letとその比較対象も、言語を統一しようと思わなければ問題ないんだろう
2023/03/27(月) 00:02:41.74ID:+gsY9S8v
ぶっちゃけRUSTでなくてもいいんだよ
安全性のためには

schemeとかHaskellみたいな言語には定義外の動作が(基本的には)存在しないという強力な安全性があるわけだし

じゃあなんでこんなにRUSTがもてはやされるのかというと、単に宣伝がうまかっただけ
2023/03/27(月) 05:32:45.27ID:UciRikyK
safe Rustには未定義動作が存在しない
そしてunsafeを用いてsafeなインタフェースを提供する時にもそれが義務付けられている
したがってそれらを用いるRustに未定義動作は存在しない
未定義動作まみれのC/C++との決定的な違いである
2023/03/27(月) 06:40:49.82ID:xp5TMlgQ
間違うヤツが悪い、って世代の規格だもんな、変に不親切は徹底してるわw
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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