C++相談室 part161

レス数が900を超えています。1000を超えると表示できなくなるよ。
2022/05/21(土) 21:23:29.59ID:kYXfaM+5
前スレ
C++相談室 part160
https://mevius.5ch.net/test/read.cgi/tech/1649979572/
2022/10/07(金) 12:54:10.56ID:p6wqSRzL
実体のポインタを list に詰まず new したものを詰んだ場合
お漏らしやタングリングポインタになるかもしれんってのもあるかな
これだと問題点が前提とは別のところになりそうではある
2022/10/07(金) 13:55:22.13ID:WQmSj+WJ
>>841
ラッパー書きゃよろしいがな

template <typename T>
class Vector: private vector<T>
{
using Base_ = vector<T>;
public:
using Base_::push_back;
using Base_::size;
const typename remove_pointer <T>::type &operator [] (size_t i) const {return *Base_::operator[] (i);}
typename remove_pointer <T>::type &operator [] (size_t i) {return *Base_::operator[] (i);}
};

Vector<X*> list;
list[i]->size();
list[i]->push_back(hoge);
list[i][j];
2022/10/07(金) 14:39:47.78ID:UqkGeV53
>>841
>  (*list[i])[j]; ←きもい
list[i]->operator [](j) ← う~ん、もっときもいかw

>>842
まあ今時生ポインタは使わんわな
shared_ptr とかを入れれば多少安全かと
2022/10/07(金) 19:06:21.61ID:E6DqXtFD
>>827
http://www.kouno.jp/home/c_faq/c2.html#6
のことでしょ?
これはもう C89 の昔から言われ続けており、太古の C99 でも
http://seclan.dll.jp/c99d/c99d04.htm#dt19990726
のとおり導入されたわけですし

今更なんですけれどね
2022/10/07(金) 19:21:05.99ID:0j3FZIjL
>>834
どう解決したのかコメントを求む
まだ憶測他で引っ張ってるし
2022/10/07(金) 19:57:27.07ID:T/Xux0J0
>>845
それはただのポインタトリックであってsizeof(info_t)が可変になる訳じゃない
というかそのページでもsizeofのこと説明してんじゃん
相変わらずの無能っすね
2022/10/07(金) 20:10:14.06ID:Znh4X5V+
>>847
元の質問>>817はサイズが可変としか言っていない
つまりsizeofが固定であり可変でないという話こそどうでもよい話
本件は>>845氏の指摘する可変なサイズの構造体を作れる話が適切に該当していると思う
2022/10/07(金) 21:32:58.03ID:WQmSj+WJ
>>819と聞いて本人は>>821と答えてるのに
何でそんな解釈を無理やりしてるのかサッパリ分からん
2022/10/08(土) 01:45:23.92ID:wlHp0G63
>>841
思い出したけど boost::ptr_vector なるものもある
2022/10/08(土) 03:10:20.17ID:fnM9fLAu
クラスメンバBの初期化が終わる前に、メンバAのコンストラクタにBのアドレスを渡すのって合法ですか?
2022/10/08(土) 08:08:39.60ID:i+QsN2sY
マルチアレーで思い出したけど、多次元配列クラスのSTL入ってどうなった?
boostとか自作クラスで対応せよってのは暴論だぜ
前者はパフォーマンス微妙だし管理されてない、後者はそれ言うなら何でもそうじゃん
2022/10/08(土) 10:25:38.57ID:a+ry7eGB
>>851
アドレス渡すだけなら合法
中身触ったら違法
2022/10/08(土) 13:47:19.43ID:wlHp0G63
>>852
template <typename T, size_t N0, size_t N1>
using multi_array = array <array <T, N0>, N1>;
2022/10/08(土) 14:59:34.51ID:0p5f7aQJ
>>854
センスね~~~
2022/10/08(土) 15:04:31.64ID:wlHp0G63
>>855
ではセンスある解を!
2022/10/08(土) 15:08:15.47ID:a+ry7eGB
>>852
std::mdarrayのことなら揉めに揉めて伸びに伸びて今は一応C++26の予定
でもまだグチグチ揉めまくって収拾がつかなそうだからもう無理じゃないかな
代わりにstd::mdspanっていう配列に被せるガワが入りそう
2022/10/08(土) 15:56:11.12ID:Ys4Rhd8B
各次元の長さが可変で、全添字の走査が速くて、メモリの並びがFortran流かC流か選べるだけで良いのに何を揉める必要があるのか
2022/10/08(土) 16:31:31.20ID:wlHp0G63
その程度なら自前で直ぐに作っちまいそうだが
標準に入ってることが意味あるんだろうな
2022/10/08(土) 18:03:00.23ID:Ys4Rhd8B
そりゃそうじゃね
「std::vectorよりも自作の配列クラスの方が優れてる」という主張が本当だったことがない
2022/10/08(土) 19:46:47.28ID:WoHyAHa2
>>849
無能君はひっこんでなさい

>>848
ですよね!
862849
垢版 |
2022/10/08(土) 20:25:53.87ID:wHqQf0MD
すいませんでしたw
2022/10/08(土) 21:43:59.65ID:cYIJtZRn
>>862
こちらこそ申し訳ございませんでしたw
2022/10/09(日) 00:52:23.28ID:KNQys/Sq
SIMD まで自分ではやりたくないのでnumpyを呼ぶのほうが早い
2022/10/09(日) 17:16:44.85ID:gpj8txwq
>>864
じゃあ全部Pythonでよくねーか?
2022/10/09(日) 20:20:03.73ID:30oWykTj
>>865
実際自分にとってはそんな感じですね。C++でpython とcudaとかopenmpを糊付けしている感覚があります
867デフォルトの名無しさん
垢版 |
2022/10/14(金) 14:32:13.11ID:hVSCfGeq
set, mapというデータ構造があります。
mapはキーと値のペアをハッシュテーブルや2分探索木に格納しているのでしょうか?
2022/10/14(金) 15:00:32.18ID:zHYXwlQW
平衡二分探索木です
ハッシュテーブル版はunordered_*です
2022/10/14(金) 15:09:19.24ID:hyLjfQu2
ハッシュテーブルの方が大抵の場面で速いと思ってええんか?
2022/10/14(金) 15:26:57.00ID:rgl2oNFZ
>>869
データの性質や使い方によるのでなんとも言いにくいが基本的にはハッシュテーブルが速いことは多い。
差し替えるのは簡単だろうし、やりたいことをとりあえずやってみて測定すればいいんでね?
2022/10/14(金) 15:33:11.96ID:IS1pk00F
>>869
実際にベンチマーク取らないとわからない。
基本的には種類が少ない場合は計算の軽い探索木が、多い場合は定数オーダーのハッシュが有利。
2022/10/14(金) 19:23:56.82ID:6Xf8KnhS
>>871
ハッシュテーブルのサイズ、という地雷的制約は好まないのですけれどもね
2022/10/15(土) 03:19:05.65ID:nP2nOTvD
std::map::operator[] は O(long(N)) のオーダーなんだが、
std::unorderd_map::operator[] のオーダーは平均で O(1) 、最悪で O(N) ということになってんよね。
意図的に最悪を引き当てる、つまり攻撃に晒されるような状況では unorderd_map のほうが不利になる可能性もある。
2022/10/15(土) 18:57:25.60ID:b3v/HVBd
C++の例外処理は、class SomeClass {}; と中身の無いクラスであっても、
throw SomeClass{}; をcatch(SomeClass) {・・・}
で受け取ることが出来るらあしいけど、
どういう仕組みでcatchは、例外の種類を識別してる?
"SomeClass"のようなclass名の文字列のポインタでも一緒に渡している
のだろうか?
typeid(x)は、RTTI(実行時型情報)が必要で、仮想関数が定義されて無いクラス
に対しては上手く働かないのではなかったっけ?
2022/10/15(土) 21:57:03.29ID:QGPaA4bd
まず基本を禿の本でも規格票でも読んで
C++例外処理ってそもそも何ってとこをわかってから
出直したら? そんな有様じゃマトモなレス付かないよ
2022/10/15(土) 23:57:29.06ID:xWZqYwiR
>>874 typeid と同等の情報で照合すれば可能ではあるんだから、何を不思議に思うことがあるのか。
「上手く働かないのでは」なんて言うぐらいならコード書いて確かめればいいだろうし。
2022/10/16(日) 01:59:22.59ID:SvF0Fhwf
>>874
例外を送出してスタックの巻き戻しをするのは例外を送出する側 (受け取る側ではなく) なんだよ。
つまり送出される例外オブジェクトの型はわかっている。
むしろどこまで巻き戻せばよいか (送出されるオブジェクトの型に対応する catch はどこにあるか) の情報が動的なものだ。
2022/10/16(日) 14:48:55.82ID:pwk0SnpM
メンバ変数をまったく使っていないメンバ関数を見つける方法ってなんかある?
CppCheckとかでできるんだっけ
2022/10/16(日) 15:16:25.24ID:r52/9r+u
まあ普通の静的解析はチェックしてくれるのでは
2022/10/16(日) 17:18:37.82ID:Y43orZLw
>>876
typeidは仮想関数を持っているクラスにしか働かないと思っていたが、
働くのか。
2022/10/16(日) 17:21:15.08ID:Y43orZLw
typeid(x)の返すオブジェクトは完全にtype_info型なのか、
それとも、type_infoを継承したクラスなのか、どっち?
2022/10/16(日) 22:40:17.52ID:SvF0Fhwf
>>881
std::type_info から派生したクラスであることはあり得る。
https://timsong-cpp.github.io/cppwp/n3337/expr.typeid#1
2022/10/17(月) 05:46:15.36ID:SQKgR2D+
それこそtypeidに聞いてみりゃいい
cout << typeid(typeid(some_one)).name();
2022/10/17(月) 22:30:57.72ID:K/vFJtXQ
T x;
T y;
に対して
x=move(y); //(1)
とした場合、時系列的に
1. move代入演算子 T::operator=(T &&a);がyの中身をxに入れる。但しこれは、2とも
 関連しているがswap(x,y)とされることもある。
 swap(x,y)を使わない場合には、xにyの中身を入れる前に元々の xの中身が削除される。
2. swapを使って無い場合には、続いてmove代入演算子 T::operator=(T &&a);が
 y のポインタメンバなどに null 値を書き込む。
3. (1)の式の最後で、右辺のオブジェクト y に対してデストラクタが呼び出される。
4. デストラクタは、y ポインタメンバが null だと何も行なわない。
 yの中身がxに交換されていた場合は、もともとxの中身だったものを削除する。

というような流れになるという理解で合ってる?
2022/10/17(月) 23:38:12.11ID:w3P18B12
実装依存では
2022/10/17(月) 23:46:42.02ID:K/vFJtXQ
>>885
特に確認したいのは、
>3. (1)の式の最後で、右辺のオブジェクト y に対してデストラクタが呼び出される。
の部分。
stroustrup氏によれば、yに対するデストラクタが必ず呼び出される、ということ
らしいが、それは常に正しいのかな?
2022/10/18(火) 00:25:45.29ID:FMJmuyaZ
>>886
> stroustrup氏によれば、yに対するデストラクタが必ず呼び出される、ということ
> らしいが、それは常に正しいのかな?
そういう型を作ることはできるけど、そんな動作をしたらスコープアウトで走るデストラクタを
止めないといけなくなって非常に使いづらくなる。正しくなさそう。
あなたが何か読み間違えてるものと思われる。
2022/10/18(火) 00:27:10.46ID:LFBcX+LO
>>887
move代入の右辺のオブジェクトは、事後にデストラクタが呼び出される、
と書いてあったと思うが。
2022/10/18(火) 03:36:36.81ID:UO6WFDjC
xの元の中身も適切に破棄されますよっていう話を歪んだ理解してそう
2022/10/18(火) 08:32:29.82ID:GEQmlbnE
>>888
[訂正]
正しくは、
・move代入演算子 T::operator=(T &&a) 自体はデストラクタを呼び出さない。
・x=move(y) と書いたとき、コンパイラが 右辺の y に対してデストラクタを呼び出す。

2つのパターンが有る。パターン1:swapを使う。パターン2:swapを使わない。
いずれにせよ、コンパイラによって y.~T() が呼び出される。

擬似等価コード:
x.operator=(rvalue(y));
y.~T();

パターン1:
T &T::operator=(T &&a) {swap(*this,a); return *this:}

パターン2:
T &T::operator=(T &&a) {thisの中身を削除; aの中身をthisにコピー; aにnull値を書き込む; return *this;}
2022/10/18(火) 08:42:53.23ID:FMJmuyaZ
>>888 あなたの読み間違いではないと主張したいなら出典を挙げられるのがよいかと。
2022/10/18(火) 12:16:32.80ID:PTXT62EI
>>888
右辺と右辺値を混同しているとかじゃない? 右辺値と右辺値参照も違う概念。

右辺値 (というか prvalue) が完結式の終わりで解体されるのは保証された動作だけど、
std::move でキャストした結果はあくまでも参照を右辺値参照として返すってだけで
元のオブジェクト (この場合は y) は依然として左辺値だよ。
y のデストラクタが呼ばれるのは y のスコープの終わりであることは保証される。
2022/10/19(水) 01:49:23.30ID:ACk8fEyB
>>892
>y のデストラクタが呼ばれるのは y のスコープの終わりであることは保証される。
なるほど。
でも結局、
T x;
T y;
x=move(y); //(1)
と書くと、(1) の部分で、
x.operator=(yを右辺値化したもの); //(2)
が行なわれて、
yの生存期間が終わる地点で、yのデストラクタであるところの y.~T() が呼び出される、
ということになることは間違いなのですね。
つまり、(2)が行なわれたら yはもはやmove後なのだから、yのデストラクタ呼び出しが
省略されるということではなく、yのデストラクタは絶対に必ず呼び出されるわけですね。
だから、T::operator=(T &&a) は、T::operator=(T &&a)の処理が終わった後に、
コンパイラによって yのデストラクタが呼び出されることを前提に処理しなければならない、
ということになる。
2022/10/19(水) 02:44:50.18ID:ACk8fEyB
>>893
誤字訂正です:
誤: ということになることは間違いなのですね。
正: ということになることは間違いないのですね。
2022/10/19(水) 04:13:29.85ID:CfflWiLk
>>893
そう。 move assignment operator と呼ばれてはいるが
右辺値であるということがわかる以上の違いはない。

ムーブは寿命を左右せず、内容の状態がどうなるかは実装次第。
具体例で言えば std::unique_ptr はムーブ後には空になる (メンバ関数 get は空ポインタを返す) ことが保証されるが、
std::string は (新たな内容が与えられるまでは) 未規定の値になる。

右辺値参照が導入されたのは C++11 からで、
デストラクタのタイミングが変わってしまうような変更を入れられるわけがない。
896デフォルトの名無しさん
垢版 |
2022/10/19(水) 23:39:12.93ID:8y/Qrf1S
C++で15年ぶりにプログラミングをすることになったんだけど、
C++11以降のことは何も知らないのでまずは復習もかねて勉強することにした
今でもbjarneの本が初心者にとって一番のテキストなの?
それとももっとシンプルで分かりやすい本が出てるのでしょうか?
2022/10/19(水) 23:45:19.38ID:w93eWlNE
>>895
今考えてみれば、条件分岐の中だけでmove代入される場合も有るからかも知れませんね。
2022/10/20(木) 03:01:20.64ID:3bh5ldea
昔のC++知ってるならとりあえずEffective Modern C++.でいいんじゃないの
2022/10/20(木) 06:31:14.16ID:pIDfWPXL
>>896
本は読者との相性があるから一概には言えないが
俺的にはやっぱ禿の本だな
変に手加減してこないところに安心感がある

ただし「プログラミング言語C++第4版」は
あくまでC++11で、C++14以後には触れていないので
構造化バインディングやコンセプトは学べない
俺はこのあたりはここやQiitaできっかけだけ拾って
あとは規格票やhttps://cpprefjp.github.io/で憶えてる
2022/10/20(木) 13:52:31.60ID:w/WeLGfC
>>896
C++ はごちゃごちゃした歴史的事情を継ぎ接ぎして出来ているので
説明を整理しようとするとかえって事情がよくわからなくなる。
どう頑張ったってそんなに簡潔にはならんよ。

場当たり的に追加された変則的なルールでも
実際に挙動に絡んでくるのなら知っておくしかしょうがないし、
きちんとした説明はそれなりの分量にもなる。
おそらく >>899 が述べる「変に手加減してこない」というのはそういう意味だと思う。
2022/10/20(木) 17:53:11.99ID:ieIEHaM0
ビャーネの本、章の構成がよく分からんのだけど何がどうしてああなったん
2022/10/20(木) 18:26:02.35ID:zGrDbuOl
昔は、ロベールが鉄板だった
2022/10/20(木) 18:47:34.03ID:sgmqUmRA
bj氏の本のダブルディスパッチの部分と、次のVisitorの部分、
どっちもよく分からなかった。
まず、前者のShape&の引数が何のためにあって、どういう役割を果たしているか
誰か教えて。
2022/10/20(木) 18:49:51.30ID:sgmqUmRA
>>903
プログラミング言語C++第四版 日本語版の
p.653, 22.3.1 ダブルディスパッチの辺りから。
bool intersect(const Shape&);
関数が無くてもこの例だと動作すると思うんだけど、
なんなん?
2022/10/20(木) 19:41:09.72ID:tMcnfqkZ
ダブルディスパッチは勘違いしやすいよね
2022/10/20(木) 23:26:04.47ID:w/WeLGfC
今でも「ロベールの C++ 入門講座」で学ぼうとしているらしいやつを Teratail や Qiita でたまに見るぞ。

C++03 と C++11 でほとんど互換性は維持されてはいるはずなんだがちょっとは非互換もあるし、
残されている機能でも今となってはあまりお勧めできないということもあるから
なるべくなら新しい本のほうがよいとは思うんだが、
俺自身が読んだことがある本が古すぎていまどきの良い本が全然わからん。
2022/10/20(木) 23:52:16.92ID:w/WeLGfC
>>904
メンバーアクセス演算子によるメンバの選択は抽象クラスなら動的 (仮想関数テーブルを辿る) だが、
引数を元にしたオーバーロード解決は静的型 (static type) の情報が元になる。

静的型はあくまでも Shape だから一旦は Shape& で受けて
オブジェクトと引数を入れ替えてもういちど intersect を呼び出すことで両方とも動的な型でディスパッチすることになるんだよ。

普通はメンバアクセスの側だけが動的ディスパッチだから二つのオブジェクトについて動的ディスパッチをするには
こういうトリックが必要になる。 ふたつの動的ディスパッチをするからダブルディスパッチなの。
2022/10/21(金) 03:42:31.85ID:sdgXBR6P
>>907
なるほど。
Shape x, y;
x.intersect(y);
とした場合、x の方は仮想関数で振り分けられるけど、yの方はそんな機能が無いから
ということのようですね。
2022/10/21(金) 19:14:57.19ID:RdD+Edtl
>>980
これは分かりにくかったかも知れません。
void func(Shape &a, Shape &b)
{
 x.intersect(y); //(1)
}

Circle c{xxx};
Box b{xxx};
func(c, b);
のような場合に、(1)において、x の部分は仮想関数によってC++のもともとの機能で
実行時の型によって動的に振り分けできるが、y については、仮想関数では
そのような意味では振り分けできないから特殊な方法が必要になる、ということですね。
2022/10/22(土) 00:28:36.65ID:76y4d7LL
>>909
訂正:
誤: void func(Shape &a, Shape &b)
正: void func(Shape &x, Shape &y)
2022/10/22(土) 21:57:41.88ID:Q+2x5vm1
モジュールはヘッダファイル・ソースファイルに代わるものと聞きました
これからは今までインクルードしていたものは全てモジュールにすればよいのでしょうか
また、グローバル変数のみのヘッダファイルや、定数のみのヘッダファイルも
モジュールにした方がよいのでしょうか
ビルド時間が速くなるそうなので気になっています
2022/10/22(土) 22:33:36.63ID:TUU3opDF
>>909
ideone に動くソースを貼ってください、全然意味がわかりません
2022/10/22(土) 22:47:49.35ID:+VggblGg
>>911
時期尚早だと思う。
現状の gcc ではオプションに -std=c++20 を付けるだけではモジュールは有効にならず、
明示的に -fmodules-ts を付ける必要があるようにしてあるので、普段使いするにはまだ早いという意図を感じる。
ドキュメントにはまだ完璧じゃないと書いてあるし。
(他のコンパイラの状況は知らんけど。)

それに C++20 の段階ではモジュールの基礎の基礎が決まっただけで
標準ライブラリすらモジュールとして再編できていない。 一応は C++23 でやることになってるけど
現在の C++ の規格は三年ごとに話がまとまった分を入れる、
つまり出来てない分を完成させるために期限を延長したりはせず三年後に先送りするという運用なので
C++23 がどこまで出来るものなのか全然わからん。
標準ライブラリを再編していく内にモジュール機能の問題点が発見されたりするかもしれん。

個人的に遊ぶ分には色々とやってみてわかったことはどんどん発信してほしいけど、
製品レベルのプロジェクトではやめておいたほうがいい。
2022/10/23(日) 00:24:14.37ID:Ti8rkbHi
>>913
msvc2022なら、と思いましたがこちらもモジュールはオプションで試験段階のようでした
もう少しvcの更新を経てから新規の小さいプロジェクトで試してみようと思います
2022/10/23(日) 06:09:10.65ID:lOKqFCBz
MSは怪しい機能は/std:c++latestにしてるよな
2022/10/23(日) 08:32:09.89ID:lOKqFCBz
C++17のfilesystemもそうだったけど
練りきれてない未完成品を無理に入れるのやめて欲しい

バグ出ししたいんなら拡張規格かoptionalとして出してみて
標準のmandatoryにするのはしっかり固まってからにしろやって

つーかSTLもboost由来のもISO以外のところでそこそこユーザに揉まれてから来たものだろ
開拓は標準規格の役目じゃねえよ
2022/10/23(日) 10:56:19.39ID:V+VjUFIF
完璧になるまで練ってたらいつまでも進まんから三年ごとに出来た分を規格に入れるという方針に変更されたんじゃないか。
不格好でも不完全でも今使えることが大事だというのは元々の理念だし。

未完成はともかく欠陥報告を乱発するのは良くはないけどさ。
2022/10/23(日) 11:55:48.92ID:d3fh3q91
使ってる所だけ直せばいいライブラリと違って(だからって良いわけじゃないけど)
モジュール作り込んでからやっぱdefectでしたって言われたら困るからなあ
2022/10/23(日) 12:11:50.11ID:ncgNttCh
ライブラリとモジュールの違いって何ですか?
2022/10/23(日) 12:51:46.87ID:d3fh3q91
使うだけの標準ライブラリと、モジュール自作する時の仕様のつもりだった
2022/10/23(日) 13:12:57.82ID:HPAI20x7
filesystemって未完成なん?
922デフォルトの名無しさん
垢版 |
2022/10/23(日) 13:25:59.97ID:lOKqFCBz
C++17の時点ではfile_clockがなかった
2022/10/23(日) 14:32:45.34ID:ecBGWNL0
file_time_type があったと思うが
924デフォルトの名無しさん
垢版 |
2022/10/23(日) 14:45:23.56ID:lOKqFCBz
あったけど使いものにならんかった
2022/10/23(日) 14:59:53.65ID:NDMzlX+C
その昔、iostreamというのがあってだな
皆阿鼻叫喚の断末魔の雄叫びを上げたもんじゃった
926デフォルトの名無しさん
垢版 |
2022/10/23(日) 16:01:34.86ID:lOKqFCBz
printfやscanfに毒舌三昧してる人に対して持っていた、お暇な方ですねという思いが蘇る
2022/10/23(日) 17:49:58.24ID:V+VjUFIF
ファイルシステムやらスレッドやらはシステム (OS) 側の都合があるからなぁ。
細かいことは環境依存の機能を使えという前提で
標準ライブラリを最小限にとどめるのは C の時代からの基本的な姿勢だっただろう。

環境依存だからこそ標準で吸収しておいてくれという気持ちもあるし、
現状が良いとも思わんけど…… なんというか……
C++ ってそういうもんだろと思って納得してるから不満には感じないな。
2022/10/23(日) 20:20:25.05ID:7je1ARgT
iosteamはいかにもC++初心者がやりそうな「オペレータをオーバーロードできるから
見た目イカすちょっとシャレた表記法にしようぜ!!」っていう厨二スピリット全開だったからな
でてきた時点で「あ、これはクソなやつだ」ってわかったよ
929デフォルトの名無しさん
垢版 |
2022/10/23(日) 20:43:19.02ID:lOKqFCBz
C with classesを始めようとして
たとえばと始めたことをずいぶん後になって
鬼の首を取ったようにキリッ
2022/10/23(日) 22:04:42.81ID:d3fh3q91
演算子チェーン自体は別に悪いもんじゃない
iostreamがクソなのはそこじゃない
2022/10/23(日) 22:42:38.11ID:9PrlG1Sf
でも競プロで何も考えずにcin >> N >> M;とかできるでしょ
2022/10/23(日) 23:18:01.98ID:a4G1Se92
なにかとiostream叩かれやすいけど
よく聞いてみると大した批判ではないよね常に
聞くに値するiostream批判ってお目にかからないね
2022/10/23(日) 23:21:04.29ID:HPAI20x7
iostreamが本当にクソならイカした再実装はあるだろう?
まさかcstdioとか言わんでくれよ
2022/10/23(日) 23:23:02.52ID:d3fh3q91
まあstd::cout << foo << bar;がつい最近まで規格上未定義動作だったのは擁護のしようがないけどな
2022/10/23(日) 23:33:00.12ID:V+VjUFIF
iostream が設計された当時は I/O のための専用の言語機能が
必要という論調があって、 Bjarne Stroustrup 氏はそれに抵抗して
当時の C++ の範疇でライブラリを作ったという経緯がある。

ここで抵抗しなければ入出力用の文法が (ライブラリとしてではなく)
言語機能として導入することになっていたかもしれないと思うと
iostream にある粗くらいは許せてしまうなぁ。

少なくとも printf みたいな型チェックがガバガバなのは C++ 的に
放置できなかったし、バッファリングと書式化をまとめつつ拡張やカスタマイズが可能で
I/O 以外も含めてストリームというインターフェイスを一般化するというのは
当時としてはこれ以上考えられない素晴らしいデザインだと思う。

ひとつこれは (iostream 設計当時でも) どうにかできただろうと思うのは
書式の変更 (マニピュレータを使うなど) をしたら陽に戻すまではそのままというのが良くなかった。
スコープを抜けたらリセットできるような方法が標準で欲しかった。
(boost にあったような気がするが名前を忘れてしまった……。)
2022/10/23(日) 23:47:22.83ID:d3fh3q91
ステートはクソで出来るだけ無くすべきっていう現代の常識が当時はなかったからな
書式をストリームのステートにしてしまったのは今思えば大失敗だがあの時代は自然な設計だったんだろうな
2022/10/23(日) 23:48:05.17ID:yEdZxD03
>>934 foo, bar がどのように定義されていたらその式が未定義動作になるの?
2022/10/23(日) 23:48:47.26ID:a4G1Se92
批判する者にその資格が無いってパティーン多々あるよな
iostream批判するやつだって
じゃあどんな素晴らしい入出力ライブラリを用意したの?
実装したの?どこの誰がどれだけ使ってるの?っていう
タダ飯喰らいがかーちゃんのご飯批判してるようなこと
2022/10/23(日) 23:55:56.29ID:RbY+y3zv
未定義じゃなくて、引数の評価順が未規定だったって話では?
2022/10/23(日) 23:56:39.14ID:d3fh3q91
>>937
何だろうと未定義(C++17以前)。なぜなら一つの式の中でstd::coutを2回変更してるから
(a+=1)+=1とか++(++a)とかも同じ
この大欠陥が見つかったせいで、式の中の評価順は基本コンパイラの好き勝手にしていいというCからの伝統を一部諦める羽目になった
2022/10/24(月) 00:00:00.66ID:9tRgjj9T
>>940
foo, bar の評価順が未規定だった件を未定義動作と勘違いしてるのか。
https://cpprefjp.github.io/lang/cpp17/expression_evaluation_order.html

cout に対する操作は関数呼び出しの内外の順序付けが入るから未定義動作にはならないよ。
レス数が900を超えています。1000を超えると表示できなくなるよ。
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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