探検
結局C++とRustってどっちが良いの?
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2023/02/25(土) 09:49:46.74ID:VRyB88xR C++の色々配慮してめんどくさい感じは好きだけど、実務になったらメモリ安全性とか考えて今後Rustに変わっていくんかな?
664デフォルトの名無しさん
2023/03/28(火) 07:15:22.07ID:qh0NVSBO >>663
それはPythonでもJavaScriptでも同じ
Web APIと関係なくプログラム独自の部分も自分でどんどんクラスを編み出して問題解決する
他を知らないためC++だけを何か特別だと思い込んでそうだな
それはPythonでもJavaScriptでも同じ
Web APIと関係なくプログラム独自の部分も自分でどんどんクラスを編み出して問題解決する
他を知らないためC++だけを何か特別だと思い込んでそうだな
665デフォルトの名無しさん
2023/03/28(火) 07:20:37.19ID:uty8q6BB >>659 をちょっとだけ擁護してみたくなっただけだよw
どこだって、ライブラリ作成者はOOPに精通してるもんだが、
C++は、OOPに精通してないと、使ってますとか公言できないもんね
むっちゃ煽られるよw その違いはあるなって思った
どこだって、ライブラリ作成者はOOPに精通してるもんだが、
C++は、OOPに精通してないと、使ってますとか公言できないもんね
むっちゃ煽られるよw その違いはあるなって思った
666デフォルトの名無しさん
2023/03/28(火) 07:41:04.68ID:qh0NVSBO OOPは精通するしないとか難しいものではないだろ
初心者かね
初心者かね
667デフォルトの名無しさん
2023/03/28(火) 07:49:36.20ID:uty8q6BB C++でOOPができるといったら、当然のようにSTLが使え、boostが使える
あるいは、traitsやattribute,constexpr を織り交ぜて、ほぼゼロサンクなバイナリを叩き出せるレベル
俺は初心者だからそのレベルにはないな
ちょっとよそよりは要求レベルは高いだろって思ってる
母語のことはちょっとだけ誇りに思ってるけど、それより、一長一短的立場
あるいは、traitsやattribute,constexpr を織り交ぜて、ほぼゼロサンクなバイナリを叩き出せるレベル
俺は初心者だからそのレベルにはないな
ちょっとよそよりは要求レベルは高いだろって思ってる
母語のことはちょっとだけ誇りに思ってるけど、それより、一長一短的立場
668デフォルトの名無しさん
2023/03/28(火) 08:58:26.51ID:C7yLEzi8 上のほうでだれかいってたけど、まともなC++erは、スマポくらい使えて当然
なんだけど…ソース単位で生ポ禁止ってのが普及しないんだよね
なんだけど…ソース単位で生ポ禁止ってのが普及しないんだよね
669デフォルトの名無しさん
2023/03/28(火) 09:04:22.01ID:u9f8RzdU newを書かなきゃ良いだけなのにね
670デフォルトの名無しさん
2023/03/28(火) 09:37:27.95ID:fedCMYV9671デフォルトの名無しさん
2023/03/28(火) 09:39:21.00ID:fedCMYV9672デフォルトの名無しさん
2023/03/28(火) 09:56:21.67ID:cZnvlJgt >>661
君がオブジェクト指向理解できてなさそう
君がオブジェクト指向理解できてなさそう
673デフォルトの名無しさん
2023/03/28(火) 10:06:33.49ID:C7yLEzi8 >>669
C++も なんでもスタックに置きたいんだけど、きつきつなのが本来なんだよね
どんどんスタックを食うのは野暮っていう流儀もある
Rust流はメモリ使用の局所化を促進するから、
メモリキャッシュまで考慮すると、悔しいけどC++より効率出る余地がある
まあ実測してみないと、知らんけどw
C++も なんでもスタックに置きたいんだけど、きつきつなのが本来なんだよね
どんどんスタックを食うのは野暮っていう流儀もある
Rust流はメモリ使用の局所化を促進するから、
メモリキャッシュまで考慮すると、悔しいけどC++より効率出る余地がある
まあ実測してみないと、知らんけどw
674デフォルトの名無しさん
2023/03/28(火) 10:06:36.56ID:vBvHBfxi >どんどんクラスを編み出して問題解決する
奴はクラスを書けたらオブジェクト指向を理解してると思ってるみたいだからな
奴はクラスを書けたらオブジェクト指向を理解してると思ってるみたいだからな
675デフォルトの名無しさん
2023/03/28(火) 10:09:59.68ID:fedCMYV9676デフォルトの名無しさん
2023/03/28(火) 10:28:38.80ID:u9f8RzdU677デフォルトの名無しさん
2023/03/28(火) 10:51:13.90ID:P0df9Gxx JavaScriptとPythonは
極力オブジェクト指向的な書き方をしないほうが
メンテナンス性も可読性も高まる言語だから
C++やC#とは事情が違うわな
極力オブジェクト指向的な書き方をしないほうが
メンテナンス性も可読性も高まる言語だから
C++やC#とは事情が違うわな
678デフォルトの名無しさん
2023/03/28(火) 17:06:18.21ID:aUMSgZvE >>662
CRTPはC++のOOPで最も効率よい実装となり必須なテクニックであるが
美しいというのはウソでむしろC++の汚さの象徴の一つになっている
初心者や他言語の人たちもいるようだからわかりやすいコード
例として各派生のadd1()を用いて共通のadd2()やadd3()などを用意する場合
template<typename T>
struct AddN {
void add2() {
static_cast<T*>(this)->add1();
static_cast<T*>(this)->add1();
}
void add3 ...略
};
struct Foo : AddN<Foo> {
int x;
Foo(int i) : x(i) {}
void add1() {
this->x++;
}
};
以上となり慣れてしまうと感覚が麻痺してしまうが
CRTP (Curiously Recurring Template Pattern)の名の通り
「Foo : AddN<Foo>」といちいち自分をパタメータとして与えなければならない
「static_cast<T*>(this)」といちいちダウンキャストをしなければならない
このように「美しくない無駄なコード」になっている
つづく
CRTPはC++のOOPで最も効率よい実装となり必須なテクニックであるが
美しいというのはウソでむしろC++の汚さの象徴の一つになっている
初心者や他言語の人たちもいるようだからわかりやすいコード
例として各派生のadd1()を用いて共通のadd2()やadd3()などを用意する場合
template<typename T>
struct AddN {
void add2() {
static_cast<T*>(this)->add1();
static_cast<T*>(this)->add1();
}
void add3 ...略
};
struct Foo : AddN<Foo> {
int x;
Foo(int i) : x(i) {}
void add1() {
this->x++;
}
};
以上となり慣れてしまうと感覚が麻痺してしまうが
CRTP (Curiously Recurring Template Pattern)の名の通り
「Foo : AddN<Foo>」といちいち自分をパタメータとして与えなければならない
「static_cast<T*>(this)」といちいちダウンキャストをしなければならない
このように「美しくない無駄なコード」になっている
つづく
679デフォルトの名無しさん
2023/03/28(火) 17:07:43.55ID:aUMSgZvE >>678のつづき
一方でRustではトレイトを用いて以下のコードとなる
C++での「美しくない無駄なコード」部分を消し去った状況とほぼ一致している
trait AddN {
fn add1(&mut self);
fn add2(&mut self) {
self.add1();
self.add1();
}
fn add3 ...略
}
struct Foo(i32);
impl AddN for Foo {
fn add1(&mut self) {
self.0 += 1;
}
}
逆にRustのこのコードと同じことを同じようにゼロコストで実現するには
C++ではCRTPを「美しくない無駄なコード」とはいえ使わざるをえない
一方でRustではトレイトを用いて以下のコードとなる
C++での「美しくない無駄なコード」部分を消し去った状況とほぼ一致している
trait AddN {
fn add1(&mut self);
fn add2(&mut self) {
self.add1();
self.add1();
}
fn add3 ...略
}
struct Foo(i32);
impl AddN for Foo {
fn add1(&mut self) {
self.0 += 1;
}
}
逆にRustのこのコードと同じことを同じようにゼロコストで実現するには
C++ではCRTPを「美しくない無駄なコード」とはいえ使わざるをえない
680デフォルトの名無しさん
2023/03/28(火) 17:58:49.48ID:C7yLEzi8681デフォルトの名無しさん
2023/03/28(火) 20:04:32.17ID:jfKwOIRn >>679
CRTPを使わないで仮想関数にすると実行時のvtable経由のオーバーヘッドがあるんだよな
Rustは何も指定しなくてもCRTPと同じ状況になるから記述はシンプルで実行時オーバーヘッドもなく速いわけか
CRTPを使わないで仮想関数にすると実行時のvtable経由のオーバーヘッドがあるんだよな
Rustは何も指定しなくてもCRTPと同じ状況になるから記述はシンプルで実行時オーバーヘッドもなく速いわけか
682デフォルトの名無しさん
2023/03/28(火) 20:17:15.74ID:fedCMYV9 そういえば初心者向けのサイト無いな
アイペンテックとか?
アイペンテックとか?
683デフォルトの名無しさん
2023/03/28(火) 20:32:01.59ID:iKmwqFtY C++のオブジェクト指向は動的ポリモーフィズムだから遅い
関数呼び出しのvtableオーバーヘッドがあるだけでなくインライン展開ができず最適化の機会も失われている
Rustは基本が静的ポリモーフィズムだからそれらのコストがなく速い
関数呼び出しのvtableオーバーヘッドがあるだけでなくインライン展開ができず最適化の機会も失われている
Rustは基本が静的ポリモーフィズムだからそれらのコストがなく速い
684デフォルトの名無しさん
2023/03/28(火) 20:33:07.14ID:QUV/Fh6a CRTP使うと全部インライン展開されるのマジで不思議だよな
685デフォルトの名無しさん
2023/03/28(火) 21:00:58.63ID:HSIaJTs3686デフォルトの名無しさん
2023/03/28(火) 21:30:24.26ID:pvMX8JEc >>627
Rubyの話はもういいよ
Rubyの話はもういいよ
687デフォルトの名無しさん
2023/03/28(火) 21:35:05.32ID:iKmwqFtY >>684
CRTPを使えば常にインライン展開されるわけではない
CRTPを使った時のみ(vtable経由にならず静的に動作が確定するため)インライン展開が可能となり最適化の可能性も広がり速くなるという話
C++ではCRTPを使わないとRustと同等の速さになれない
CRTPを使えば常にインライン展開されるわけではない
CRTPを使った時のみ(vtable経由にならず静的に動作が確定するため)インライン展開が可能となり最適化の可能性も広がり速くなるという話
C++ではCRTPを使わないとRustと同等の速さになれない
688デフォルトの名無しさん
2023/03/28(火) 22:58:28.07ID:rZiXTukV vtableが重く感じるとかどんな環境やねん。どうせエアプやろ。
689デフォルトの名無しさん
2023/03/28(火) 23:08:36.42ID:u9f8RzdU 呼び出し回数多いと馬鹿にならんよ
690デフォルトの名無しさん
2023/03/29(水) 00:01:28.04ID:jlgG+N1i vtableが重いというよりインライン展開+αの最適化が効かなくなるのが問題なんでしょ
使ってる関数が常に固定値(nullとか)を返すって事前に分かればそれによって分岐の整理ができたりするけど
間にvtableが挟まるとそういう予測が難しくなる
使ってる関数が常に固定値(nullとか)を返すって事前に分かればそれによって分岐の整理ができたりするけど
間にvtableが挟まるとそういう予測が難しくなる
691デフォルトの名無しさん
2023/03/29(水) 00:09:55.54ID:jqKX3lj0 >>687
CRTPを使わないと真に実現できないのはメソッド記法だけ
そしてvtableとインライン展開に君が想像するような関係性は無い
というか、同じ推論をRustで適用すれば「object-safeなtraitへのimplはvtableを量産しインライン展開を阻害するので悪、やめろ」ということにならないかい?
自分が何を書こうとしているのかよく考えてから書き込むことだ
CRTPを使わないと真に実現できないのはメソッド記法だけ
そしてvtableとインライン展開に君が想像するような関係性は無い
というか、同じ推論をRustで適用すれば「object-safeなtraitへのimplはvtableを量産しインライン展開を阻害するので悪、やめろ」ということにならないかい?
自分が何を書こうとしているのかよく考えてから書き込むことだ
692デフォルトの名無しさん
2023/03/29(水) 00:26:00.18ID:hbkToQM4 C++もRustも、OOPなアセンブラの用途があるからね
少々vtableを経ても平気だとしても、そういうバイナリ吐いてほしくないときはある
バイナリは覗かれるもの
少々vtableを経ても平気だとしても、そういうバイナリ吐いてほしくないときはある
バイナリは覗かれるもの
693デフォルトの名無しさん
2023/03/29(水) 02:17:33.72ID:0e8thR9U こういうしょーもない連中に限ってvtableによって速度が何%落ちるかなんて測ったこともないんだよ。
馬鹿馬鹿しい。
馬鹿馬鹿しい。
694デフォルトの名無しさん
2023/03/29(水) 03:03:32.31ID:F3x5gAOr695デフォルトの名無しさん
2023/03/29(水) 08:27:05.33ID:hbkToQM4 >>693
パフォーマンスを測るまでもなく、吐かれるバイナリの汚さ
書いた一言一句が何になるか、気になって仕方ないのがC++erだよ(諸派あり、用途にもよる
バイナリエディタに放り込んだらわかるまである
パフォーマンスを測るまでもなく、吐かれるバイナリの汚さ
書いた一言一句が何になるか、気になって仕方ないのがC++erだよ(諸派あり、用途にもよる
バイナリエディタに放り込んだらわかるまである
696デフォルトの名無しさん
2023/03/29(水) 08:41:42.91ID:jqKX3lj0697デフォルトの名無しさん
2023/03/29(水) 09:39:43.93ID:gptXJHJd この英語版wikipediaのC++サンプルコードとコンパイル結果が詳しい
https://en.wikipedia.org/wiki/Virtual_method_table#Example
CRTPを使わないとvirtual method tableが出てきて不利になる
https://en.wikipedia.org/wiki/Virtual_method_table#Example
CRTPを使わないとvirtual method tableが出てきて不利になる
698デフォルトの名無しさん
2023/03/29(水) 10:58:30.49ID:DCEr0ZuV CRTPが嫌ならテンプレート分ければいいだけでは?
699デフォルトの名無しさん
2023/03/29(水) 11:49:15.76ID:KmrCY6Bh >>678
これってダウンキャスト入ってるから危険なこともできそう
相当するコードはRustではコンパイル通らない?
#include <iostream>
#define DOUT(arg) std::cout << #arg": " << arg << std::endl
template<typename T> struct AddN {
void add2() {
static_cast<T*>(this)->add1();
static_cast<T*>(this)->add1();
}
};
struct Foo : AddN<Foo> {
int x;
Foo(int i) : x(i) {}
void add1() {
this->x++;
}
};
struct Bar : AddN<Foo> {
double y;
Bar(double i) : y(i) {}
void add1() {
this->y+=0.1;
}
};
int main () {
Foo foo (1); Bar bar (0.1);
DOUT (foo.x); DOUT (bar.y);
foo.add1 (); bar.add1 ();
DOUT (foo.x); DOUT (bar.y);
return 0;
}
これってダウンキャスト入ってるから危険なこともできそう
相当するコードはRustではコンパイル通らない?
#include <iostream>
#define DOUT(arg) std::cout << #arg": " << arg << std::endl
template<typename T> struct AddN {
void add2() {
static_cast<T*>(this)->add1();
static_cast<T*>(this)->add1();
}
};
struct Foo : AddN<Foo> {
int x;
Foo(int i) : x(i) {}
void add1() {
this->x++;
}
};
struct Bar : AddN<Foo> {
double y;
Bar(double i) : y(i) {}
void add1() {
this->y+=0.1;
}
};
int main () {
Foo foo (1); Bar bar (0.1);
DOUT (foo.x); DOUT (bar.y);
foo.add1 (); bar.add1 ();
DOUT (foo.x); DOUT (bar.y);
return 0;
}
700デフォルトの名無しさん
2023/03/29(水) 11:51:44.76ID:KmrCY6Bh 実行したら以下のようになった
$ ./a.out
foo.x: 1
bar.y: 0.1
foo.x: 2
bar.y: 0.2
最後のbar.yは1.1になると思ってたんだがはて?
$ ./a.out
foo.x: 1
bar.y: 0.1
foo.x: 2
bar.y: 0.2
最後のbar.yは1.1になると思ってたんだがはて?
701デフォルトの名無しさん
2023/03/29(水) 12:42:03.29ID:KmrCY6Bh そもそもBarはFooを継承してないんだから
ダウンキャストのところでコンパイルエラー出て良いようなもんだけど
何で通すんだろ? templateだとチェックを緩和してるのかな?
あるいはコンパイラのバグかな?
$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
ダウンキャストのところでコンパイルエラー出て良いようなもんだけど
何で通すんだろ? templateだとチェックを緩和してるのかな?
あるいはコンパイラのバグかな?
$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
702デフォルトの名無しさん
2023/03/29(水) 12:43:14.11ID:KmrCY6Bh -ダウンキャストのところでコンパイルエラー出て良いようなもんだけど
+static_cast<T*>(this)->add1();のところでコンパイルエラー出て良いようなもんだけど
+static_cast<T*>(this)->add1();のところでコンパイルエラー出て良いようなもんだけど
703デフォルトの名無しさん
2023/03/29(水) 12:55:36.31ID:jlgG+N1i 最近のC++はよく分からんけどその例だとadd2使わないと多分変なことにならない
doubleをint扱いして1足しても1/(2^53)(←不正確、指数部による)くらいしか変動しないのかな
FooもBarもAddN継承してるからstatic_castでコンパイルエラーは出ないはず
Rustはクラス継承がないからstatic_castとの正確な比較はできない
traitで似たようなコード書くときはSelfキーワードで自分の型を指すからダウンキャスト必要ないし
敢えてstatic_castと対応させるならtransmuteだろうけどunsafe付きの関数だから危険でもコンパイルは通せる
(unsafeを使う範囲の安全性保証はプログラマの責任)
doubleをint扱いして1足しても1/(2^53)(←不正確、指数部による)くらいしか変動しないのかな
FooもBarもAddN継承してるからstatic_castでコンパイルエラーは出ないはず
Rustはクラス継承がないからstatic_castとの正確な比較はできない
traitで似たようなコード書くときはSelfキーワードで自分の型を指すからダウンキャスト必要ないし
敢えてstatic_castと対応させるならtransmuteだろうけどunsafe付きの関数だから危険でもコンパイルは通せる
(unsafeを使う範囲の安全性保証はプログラマの責任)
704デフォルトの名無しさん
2023/03/29(水) 13:10:19.46ID:KmrCY6Bh >>703
>最近のC++はよく分からんけどその例だとadd2使わないと多分変なことにならない
あーごめんごめん!興味があったのはadd2を呼んだときの挙動だった
- foo.add1 (); bar.add1 ();
+ foo.add2 (); bar.add2 ();
$ ./test
foo.x: 1
bar.y: 0.1
foo.x: 3
bar.y: 0.1 <- 鼻から悪魔
>FooもBarもAddN継承してるからstatic_castでコンパイルエラーは出ないはず
なるほどキャストしているthisはAddN<Foo>*だから
Foo*にもBar*にもダウンキャストできるってことね
ありがとう
>最近のC++はよく分からんけどその例だとadd2使わないと多分変なことにならない
あーごめんごめん!興味があったのはadd2を呼んだときの挙動だった
- foo.add1 (); bar.add1 ();
+ foo.add2 (); bar.add2 ();
$ ./test
foo.x: 1
bar.y: 0.1
foo.x: 3
bar.y: 0.1 <- 鼻から悪魔
>FooもBarもAddN継承してるからstatic_castでコンパイルエラーは出ないはず
なるほどキャストしているthisはAddN<Foo>*だから
Foo*にもBar*にもダウンキャストできるってことね
ありがとう
705デフォルトの名無しさん
2023/03/29(水) 13:47:10.36ID:KmrCY6Bh 正当?なC++的にはdynamic_castすべきなんじゃなかろうかって思うんだよね
でそれはvtable介してadd1にアクセスするのと変わらない
プログラマの責任でstatic_castして効率化する
ってテクニックは俺は割と好きだけども
でそれはvtable介してadd1にアクセスするのと変わらない
プログラマの責任でstatic_castして効率化する
ってテクニックは俺は割と好きだけども
706デフォルトの名無しさん
2023/03/29(水) 14:18:14.91ID:JN59fMMe >>703
transmuteはダウンキャストではなく任意の型同士の強引な型変換(読み替え)だから当然unsafe
一方でダウンキャストは親から子、基底から派生、抽象から具体への変換を指す
Rustの場合は抽象的なトレイトから具体的な型への変換がダウンキャストとなる
Rustは基本的には静的ポリモーフィズムで
コンパイル時点で各具体的な型のコードへ安全に置き換わるモノモーフィズムなので
C++のstatic_castのような危険のあるダウンキャストを必要としないが正解
Rustでもdyn Traitを用いた場合のみ動的ポリモーフィズムとなり
C++のdynamic_castと同様に実行時ダウンキャストがdowncast()/downcast_ref()/downcast_mut()で可能だが
C++とは異なりRustはNull安全でダウンキャストできる
transmuteはダウンキャストではなく任意の型同士の強引な型変換(読み替え)だから当然unsafe
一方でダウンキャストは親から子、基底から派生、抽象から具体への変換を指す
Rustの場合は抽象的なトレイトから具体的な型への変換がダウンキャストとなる
Rustは基本的には静的ポリモーフィズムで
コンパイル時点で各具体的な型のコードへ安全に置き換わるモノモーフィズムなので
C++のstatic_castのような危険のあるダウンキャストを必要としないが正解
Rustでもdyn Traitを用いた場合のみ動的ポリモーフィズムとなり
C++のdynamic_castと同様に実行時ダウンキャストがdowncast()/downcast_ref()/downcast_mut()で可能だが
C++とは異なりRustはNull安全でダウンキャストできる
707デフォルトの名無しさん
2023/03/29(水) 14:59:38.14ID:hbkToQM4 そこは、わずかにコストを支払って、reinterpret_castでもいいとは思うけどね
708デフォルトの名無しさん
2023/03/29(水) 15:00:17.60ID:hbkToQM4 ああちがう、reinterpret_castを避ける、だ
709デフォルトの名無しさん
2023/03/29(水) 15:30:35.32ID:jlgG+N1i 動的検査のコストよりもキャストに失敗した時の分岐処理のせいで最適化が阻害されるのを問題視してる感じ
かといって分岐しないなら動的検査の意味ないし
かといって分岐しないなら動的検査の意味ないし
710デフォルトの名無しさん
2023/03/29(水) 15:35:36.31ID:jd4hHaC+711デフォルトの名無しさん
2023/03/29(水) 15:40:07.88ID:R/bWJVR7 Rustのポインタ(参照)のNull安全ってすごく上手い仕組みだな
C++のdynamic_castもRustのdowncast_refも生成コードはどちらもダウンキャスト成功時はそのままポインタを返して失敗時は0を返す点で効率も同じだけど
Rustでは返す型としてはそれをポインタで直接に表さずにOption<&T>を返すと表現させて
成功時はOption::Some(&T)を返して失敗時の0はOption::Noneとして返すため
プログラムコード上はNoneかSomeか生成コードでは0か否かをチェックせずには使えないわけだ
C++でのNullポインタか否かのチェック忘れを静的な型チェックで防止できるってことは
もしかしてC++でもdynamic_castやその他のNullポインタを返すライブラリ全てをstd::optionalを返すように変更すればNull安全になるんじゃないか?
C++のdynamic_castもRustのdowncast_refも生成コードはどちらもダウンキャスト成功時はそのままポインタを返して失敗時は0を返す点で効率も同じだけど
Rustでは返す型としてはそれをポインタで直接に表さずにOption<&T>を返すと表現させて
成功時はOption::Some(&T)を返して失敗時の0はOption::Noneとして返すため
プログラムコード上はNoneかSomeか生成コードでは0か否かをチェックせずには使えないわけだ
C++でのNullポインタか否かのチェック忘れを静的な型チェックで防止できるってことは
もしかしてC++でもdynamic_castやその他のNullポインタを返すライブラリ全てをstd::optionalを返すように変更すればNull安全になるんじゃないか?
712デフォルトの名無しさん
2023/03/29(水) 15:45:49.19ID:RttupHdJ713デフォルトの名無しさん
2023/03/29(水) 17:50:54.05ID:aWl/4JyA714デフォルトの名無しさん
2023/03/29(水) 18:18:44.67ID:eKurmGUm たぶん人違いじゃないかな?
dynamic_castの返り値を確認しないやつは
流石におらんと思うよ
静的に確認してくれても全く嬉しくない
dynamic_castの返り値を確認しないやつは
流石におらんと思うよ
静的に確認してくれても全く嬉しくない
715デフォルトの名無しさん
2023/03/29(水) 18:19:38.85ID:eKurmGUm 訂正
静的に確認を強制されても嬉しくない
静的に確認を強制されても嬉しくない
716デフォルトの名無しさん
2023/03/29(水) 18:50:51.61ID:3DtieHtv ヌルポインタが返る全ての関数についてそうしないとヌル安全にならない
ヌルを使ってはダメ
ヌルを使ってはダメ
717デフォルトの名無しさん
2023/03/29(水) 19:05:30.65ID:KmrCY6Bh それは当然だよ
C++では指し示した先にインスタンスがあるかどうか
分からんときにのみポインタを使う
確実にあるときは参照を使うのが流儀
ポインタが使われるところではnullptrのチェックを行う
この流儀の部分を守らないスカタンが問題なんだな
Cに参照がないので上記流儀が守られないことも問題
C++では指し示した先にインスタンスがあるかどうか
分からんときにのみポインタを使う
確実にあるときは参照を使うのが流儀
ポインタが使われるところではnullptrのチェックを行う
この流儀の部分を守らないスカタンが問題なんだな
Cに参照がないので上記流儀が守られないことも問題
718デフォルトの名無しさん
2023/03/29(水) 19:30:08.82ID:ap6Xt56V719デフォルトの名無しさん
2023/03/29(水) 19:36:28.24ID:KmrCY6Bh >>718
BarはAddN<Bar>ではなくAddN<Foo>を継承しているから
BarはAddN<Bar>ではなくAddN<Foo>を継承しているから
720デフォルトの名無しさん
2023/03/29(水) 19:41:07.31ID:ap6Xt56V721デフォルトの名無しさん
2023/03/29(水) 19:53:07.69ID:KmrCY6Bh templateを展開すると
void Add <Foo>::add2() {
static_cast<Foo*>(this)->add1();
static_cast<Foo*>(this)->add1();
}
thisはBarの基底AddN<Foo>*のポインタ
これをBarと無関係のFoo*にキャストしたら動作は不定
void Add <Foo>::add2() {
static_cast<Foo*>(this)->add1();
static_cast<Foo*>(this)->add1();
}
thisはBarの基底AddN<Foo>*のポインタ
これをBarと無関係のFoo*にキャストしたら動作は不定
722デフォルトの名無しさん
2023/03/29(水) 20:09:37.10ID:ap6Xt56V なるほど
浮動小数点に対してそれを整数と見て+2してしまっているのかな
本来はコンパイル段階でエラーにしないとやばそうだ
今回はっきり動いていないとわかるケースだからいいけど何となく動いてしまってるケースがあると恐ろしい
浮動小数点に対してそれを整数と見て+2してしまっているのかな
本来はコンパイル段階でエラーにしないとやばそうだ
今回はっきり動いていないとわかるケースだからいいけど何となく動いてしまってるケースがあると恐ろしい
723デフォルトの名無しさん
2023/03/29(水) 20:11:29.28ID:KmrCY6Bh 正当?なC++的にはdynamic_castすべきだと思うんだよね
template<typename T> struct AddN {
void add2() {
dynamic_cast<T&>(*this).add1();
dynamic_cast<T&>(*this).add1();
}
virtual ~AddN () {};
};
template<typename T> struct AddN {
void add2() {
dynamic_cast<T&>(*this).add1();
dynamic_cast<T&>(*this).add1();
}
virtual ~AddN () {};
};
724デフォルトの名無しさん
2023/03/29(水) 20:13:55.05ID:AtW1ukjc 静的に一意に決まるんならいいのでは
725デフォルトの名無しさん
2023/03/29(水) 20:29:34.23ID:KmrCY6Bh 俺は割と好きだけどもね
726デフォルトの名無しさん
2023/03/29(水) 20:42:15.15ID:rGt9yURA C++最適化効きすぎてadd2そのものが展開されて最短コードにしかならん
727デフォルトの名無しさん
2023/03/29(水) 20:50:49.78ID:ij9aGzzi doubleのビット列をintとして扱ってインクリメントしてるから結果がおかしいんだろ
なぜコンパイラは型不一致エラーを出せないんだ?
なぜコンパイラは型不一致エラーを出せないんだ?
728デフォルトの名無しさん
2023/03/29(水) 21:21:00.23ID:iEVzPlea 問題があれば何でもコンパイル時点でエラーを出してくれるRustを使おう
実行デバッグが激減して開発効率も高い
実行デバッグが激減して開発効率も高い
729デフォルトの名無しさん
2023/03/29(水) 21:39:38.92ID:KmrCY6Bh でもunsafeないとダメなんでしょ?
730デフォルトの名無しさん
2023/03/29(水) 22:02:01.80ID:iEVzPlea 普通のプログラムでunsafeは出てこない
731デフォルトの名無しさん
2023/03/29(水) 23:01:50.75ID:UIOCT5jB ライブラリが一個もない状態から基本的なライブラリを作るためにunsafeが必要という話だったら
有限個のバイナリファイルが正しく出力されればいいだけなので
ソースコードをチェックしなくても出力をチェックすればいいのでは?
有限個のバイナリファイルが正しく出力されればいいだけなので
ソースコードをチェックしなくても出力をチェックすればいいのでは?
732デフォルトの名無しさん
2023/03/30(木) 06:54:28.38ID:xjlzONIR733デフォルトの名無しさん
2023/03/30(木) 06:54:54.18ID:uZvbGS3c そういえばJavaが全然話題にもならないが言語のヒエラルキーって
C++ 最強カミソリ
剃り残しナシ
Rust 安全カミソリ
キレテナーィ なまくら
C# イケてるが
GCがあるからダメぽ
Java 論外
ヌルポとGCがあるからダメぽ
こんな感じ?
C++ 最強カミソリ
剃り残しナシ
Rust 安全カミソリ
キレテナーィ なまくら
C# イケてるが
GCがあるからダメぽ
Java 論外
ヌルポとGCがあるからダメぽ
こんな感じ?
734デフォルトの名無しさん
2023/03/30(木) 07:08:43.78ID:xjlzONIR 一つ間違うと自分の手とか余計なところまで切れちゃうw
735デフォルトの名無しさん
2023/03/30(木) 07:25:50.11ID:xjlzONIR 俺にとってのC++は、日本語だよ 物心ついたときには、C++だったんだ
氏ぬまで忘れないと思う だからある意味最強、そんな奴が結構多いんだと思う
「ちゃんと話せ」って躾けられたのも、良し悪し
氏ぬまで忘れないと思う だからある意味最強、そんな奴が結構多いんだと思う
「ちゃんと話せ」って躾けられたのも、良し悪し
736デフォルトの名無しさん
2023/03/30(木) 07:29:05.38ID:Lly0YXlC737デフォルトの名無しさん
2023/03/30(木) 07:42:11.73ID:w91B/KcY C++が出来なくてRustが出来ることってある?
738デフォルトの名無しさん
2023/03/30(木) 07:43:46.76ID:xjlzONIR 縛りプレイ
739デフォルトの名無しさん
2023/03/30(木) 08:01:00.44ID:Lly0YXlC740デフォルトの名無しさん
2023/03/30(木) 08:18:36.82ID:PJ70lfxq プリミティブはいろいろ備わってるから、やってできなくはないんだろうけど、
強制する方法がないから、ちっとも普及しないんだよね
強制する方法がないから、ちっとも普及しないんだよね
741デフォルトの名無しさん
2023/03/30(木) 08:28:14.61ID:Lly0YXlC >>740
C++はそのプリミティブを多数欠いている
まさか代数的データ型をunionで頑張ればできると主張するのか?
パターンマッチングは構文だからC++には無理
データ競合を静的に検知する方法もない
C++はそのプリミティブを多数欠いている
まさか代数的データ型をunionで頑張ればできると主張するのか?
パターンマッチングは構文だからC++には無理
データ競合を静的に検知する方法もない
742デフォルトの名無しさん
2023/03/30(木) 08:32:28.84ID:PJ70lfxq C/C++には昔から、「なければgenerateすればいいじゃん」っていう文化がある
パターンマッチングは、いまどきIDEが記述支援するんだから、やってできなくはない
データ競合やらは、「そういう」スマポを導入すればいい
でもね、みんな使わないんだわ 使われないものは、ないものとして詰られても仕方ない
あ、Cとおんなじように、入れ子になった構造体をささっと書きたいとかは思うね
もうできるようになったっけ?
パターンマッチングは、いまどきIDEが記述支援するんだから、やってできなくはない
データ競合やらは、「そういう」スマポを導入すればいい
でもね、みんな使わないんだわ 使われないものは、ないものとして詰られても仕方ない
あ、Cとおんなじように、入れ子になった構造体をささっと書きたいとかは思うね
もうできるようになったっけ?
743デフォルトの名無しさん
2023/03/30(木) 08:35:47.70ID:2ioUidZk Rustのマクロって結構凄くね?
744デフォルトの名無しさん
2023/03/30(木) 09:18:55.32ID:PJ70lfxq …いやまてよ、パターンマッチングって、エラー等検出のことだと思ってたけど、
パターンマッチング Rust でぐぐったら全然違うものが出てきたぜ その節は撤回 ちょっと読んでみる
パターンマッチング Rust でぐぐったら全然違うものが出てきたぜ その節は撤回 ちょっと読んでみる
745デフォルトの名無しさん
2023/03/30(木) 10:37:10.30ID:z+Rtq9PG r
746デフォルトの名無しさん
2023/03/30(木) 10:45:06.95ID:7YA3tv0i std::visitはパターンマッチに含まれますか
747デフォルトの名無しさん
2023/03/30(木) 10:56:39.82ID:7YA3tv0i こういうのね
提案段階の機能を除けば一番直和型を直接的に表現できていると思う
https://www.modernescpp.com/index.php/visiting-a-std-variant-with-the-overload-pattern
提案段階の機能を除けば一番直和型を直接的に表現できていると思う
https://www.modernescpp.com/index.php/visiting-a-std-variant-with-the-overload-pattern
748デフォルトの名無しさん
2023/03/30(木) 10:58:13.17ID:xP+9HiJo パターンマッチングはC++23に入れようとしたがRustと比べて機能も弱すぎて失敗している
Rustのパターンマッチングはこんな感じで記述性や可読性を向上させている
fn slice_pattern(slice: &[(i32, i32)]) {
match slice {
[] => println!("空です"),
[(a, b)] => println!("要素は1つで({a},{b})です"),
[_, (123, b), ..] => println!("2つ目の前者が123なものは(123,{b})です"),
[.., next_last, _] => println!("その他の最後から2つ目の要素は{next_last:?}です"),
}
}
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:?}です"),
}
}
fn struct_pattern() {
let a = Foo { bar: 123, baz: 456, qux: 789 };
let b = Foo { baz: 555, ..a };
for Foo { bar, baz, qux } in &[a, b] {
println!("Foo: bar={bar}, baz={baz}, qux={qux}");
}
}
fn range_pattern(c: char) {
match c {
'0'..='9' => println!("数字({c})です"),
'a'..='z' | 'A'..='Z' => println!("アルファベット({c})です"),
_ => println!("その他の文字({c})です"),
}
}
Rustのパターンマッチングはこんな感じで記述性や可読性を向上させている
fn slice_pattern(slice: &[(i32, i32)]) {
match slice {
[] => println!("空です"),
[(a, b)] => println!("要素は1つで({a},{b})です"),
[_, (123, b), ..] => println!("2つ目の前者が123なものは(123,{b})です"),
[.., next_last, _] => println!("その他の最後から2つ目の要素は{next_last:?}です"),
}
}
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:?}です"),
}
}
fn struct_pattern() {
let a = Foo { bar: 123, baz: 456, qux: 789 };
let b = Foo { baz: 555, ..a };
for Foo { bar, baz, qux } in &[a, b] {
println!("Foo: bar={bar}, baz={baz}, qux={qux}");
}
}
fn range_pattern(c: char) {
match c {
'0'..='9' => println!("数字({c})です"),
'a'..='z' | 'A'..='Z' => println!("アルファベット({c})です"),
_ => println!("その他の文字({c})です"),
}
}
749デフォルトの名無しさん
2023/03/30(木) 11:05:35.09ID:wHEiYRW7 C++はユーザが多いので標準でなくてもライブラリがあるからね
Rustはユーザが少ないので標準で用意しとく必要がある
パタンマッチングは言語の話だけども
Rustはユーザが少ないので標準で用意しとく必要がある
パタンマッチングは言語の話だけども
750デフォルトの名無しさん
2023/03/30(木) 11:06:04.96ID:dh4KEwq/ Rust の TcpListener のサンプルについて質問です
1ページ目は無料で1ページ目だけで動作するはずですが
https://xtech.nikkei.com/atcl/nxt/column/18/01920/081600022/
何故か1byteしか受け取らず常に 404 NotFound になります
何処を治せばよいですか?
1ページ目は無料で1ページ目だけで動作するはずですが
https://xtech.nikkei.com/atcl/nxt/column/18/01920/081600022/
何故か1byteしか受け取らず常に 404 NotFound になります
何処を治せばよいですか?
751デフォルトの名無しさん
2023/03/30(木) 11:14:15.70ID:xP+9HiJo752デフォルトの名無しさん
2023/03/30(木) 11:14:43.48ID:PJ70lfxq 一発目から GET / HTTP/1.1 じゃないものが来てるかもよ、buffer 表示させてみては
753デフォルトの名無しさん
2023/03/30(木) 11:28:11.87ID:7YA3tv0i >>751
記事読んだ?
記事読んだ?
754デフォルトの名無しさん
2023/03/30(木) 11:32:57.91ID:xP+9HiJo755デフォルトの名無しさん
2023/03/30(木) 11:39:46.03ID:PJ70lfxq パターンマッチングの件、5分くらい読んできた
そういう風に書きたいっていうニーズがあるんだな、表現力を誇るC++でこれが書けないのは確かに手落ちw
この型はあれでもこれでもあるっていうの、あんまり扱ってこなかったけど、
上手く書けば便利になるかもね ただし、ゼロサンクでね
そういう風に書きたいっていうニーズがあるんだな、表現力を誇るC++でこれが書けないのは確かに手落ちw
この型はあれでもこれでもあるっていうの、あんまり扱ってこなかったけど、
上手く書けば便利になるかもね ただし、ゼロサンクでね
756デフォルトの名無しさん
2023/03/30(木) 11:39:46.85ID:xP+9HiJo >>750
そのRustのTcpListenerのサンプル動かしてみたけど普通に動いた
返すindex.htmlを用意してcargo run
ブラウザからhttp://localhost:9999/で表示された
そのRustのTcpListenerのサンプル動かしてみたけど普通に動いた
返すindex.htmlを用意してcargo run
ブラウザからhttp://localhost:9999/で表示された
757デフォルトの名無しさん
2023/03/30(木) 11:46:33.32ID:7YA3tv0i758デフォルトの名無しさん
2023/03/30(木) 11:47:15.19ID:xP+9HiJo759デフォルトの名無しさん
2023/03/30(木) 11:49:39.34ID:xP+9HiJo760デフォルトの名無しさん
2023/03/30(木) 11:58:04.66ID:7YA3tv0i761デフォルトの名無しさん
2023/03/30(木) 11:58:20.56ID:PJ70lfxq 教科書的サンプルとは別に、実践的なサンプルが見たいぞ
必要だから入った仕様だろう、手ごろにどっかあるはずだ お勧めのやつをたのむ
必要だから入った仕様だろう、手ごろにどっかあるはずだ お勧めのやつをたのむ
762デフォルトの名無しさん
2023/03/30(木) 11:59:10.65ID:wHEiYRW7 >>751
>>749>パタンマッチングは言語の話だけども
>例えば>>748のShapeの定義例は
>enum Shape {
> Circle(u32),
> Rectangle(u32, u32),
> Parallelogram(u32, u32),
>}
>これだけで済む
>さらに型Shapeに対して様々なメソッドを実装できる
>C++ではそれぞれ困難と不可能
横レスだけども
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);
// void function (ostream &os, const Parallelogram &p);
}
>>749>パタンマッチングは言語の話だけども
>例えば>>748のShapeの定義例は
>enum Shape {
> Circle(u32),
> Rectangle(u32, u32),
> Parallelogram(u32, u32),
>}
>これだけで済む
>さらに型Shapeに対して様々なメソッドを実装できる
>C++ではそれぞれ困難と不可能
横レスだけども
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);
// void function (ostream &os, const Parallelogram &p);
}
763デフォルトの名無しさん
2023/03/30(木) 12:23:51.98ID:8gDdaVz7 >>762
それだとShapeが型ではなく名前空間になってしまってるからダメでしょ
それだとShapeが型ではなく名前空間になってしまってるからダメでしょ
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 「もうキモくてキモくて…」29歳女性が語る“おぢアタック”の実態。「俺ならイケるかも」年下女性を狙う勘違い中年男性には共通点が [Hitzeschleier★]
- テレビ朝日 本社から男性が転落し死亡。関連会社社員か 当たった通行人が左肩軽傷 [阿弥陀ヶ峰★]
- 中国軍機がレーダー照射 小泉防衛大臣の説明に「矛盾している」中国外務省報道官が批判 [♪♪♪★]
- テレビ朝日本社から20~30代の関連会社社員とみられる男性が転落し死亡 六本木けやき坂通りの通行人にはけが人なし [少考さん★]
- 「これいいじゃん!!!」 セブン-イレブンの1620円で買える“1人用クリスマスケーキ”🎂に注目殺到「天才すぎる」 [パンナ・コッタ★]
- 高市早苗首相が天理教系企業に“巨額発注” 総額5000万円 本人は「政治団体の活動に必要な支出」と回答 ★2 [Hitzeschleier★]
- 自認トトロなんだが
- 【乞食速報】プロクオリティ ビーフカレー 96食 4262円 [268244553]
- 【実況】博衣こよりのえちえちスーパーダンガンロンパ7🧪
- enaga(´・Ǎ・`) ◆99xH8ena32 ってコテわろたwwwwwwwwwww
- 年末のvip芋煮会って何日だっけ?
- 正常位と対面座位だとイけないんだけど自分だけか?
