23/10/31 08:59:52.78 DBRUqQAF0.net
>1 乙です
前スレ 例外はループ脱出に使うような物じゃない、との意見に賛成です。
自分は、例外は「起こり得るけどいちいちエラー処理を書いたらアホな話を」「処理呼び出し毎ではないレベルで」「エラー対処コーディングするもの」と思ってます。
具体例は、
リンクリストなどコレクション操作でメモリ不足が起きた場合、のエラー処理。
コレクションの追加や削除を頻繁に行うコードって、大体はもっと概念レベルが高い事をやってるので、1件の追加 レベルでエラー処理書いてたらアホな感じになる。
しかも、GUI プロセスを作ってて何か上手く動かないから特定のエラーだけを画面に表示したい、など、ことさら明確に対処したい場合です。プロセスが落ちればいいだけなら、main()の外側、の仕様がやってくれる。
古い本の情報だけど、SBリップマンによると、MS VC++と、sun、hp-ux の C++コンパイラで、例外を使う/使わないで速度性能調査したそうで、 4~6% の速度劣化があったとの事です。
3:デフォルトの名無しさん
23/10/31 09:37:52.87 BnGGo/620.net
スレ終了間際に現れる質問いいですかオジなんなの?w.
4:デフォルトの名無しさん
23/10/31 09:38:43.79 yneNhI3/d.net
Pythonで言うと
forのStopIterationは へっ? だし
int()のValueErrorですら微妙
5:デフォルトの名無しさん
23/10/31 11:32:52.74 5ddE/sJo0.net
うるせえstd::stoi()ぶつけんぞ
6:デフォルトの名無しさん (アウアウウー Sad5-U1R4)
23/10/31 16:49:04.12 Xd7Dooyma.net
>>3
ヘッダーの最後の行の #endif みたいなものだよ
7:デフォルトの名無しさん (ワッチョイ 6105-NMSe)
23/10/31 23:53:09.44 BnGGo/620.net
>>6
と、言うことは対になる#ifがどこかに?
8:デフォルトの名無しさん (ワッチョイ 1945-FUJr)
23/11/01 10:50:51.42 NLQyML8a0.net
…(いくら5chとは言え、複数の人が集まる場所で、何かを教えて頂いてもお礼も言えず、面白い返しもできない人がいたとして。その人がプログラムに関してだけは素晴らしいコードを書ける、なんてことはあるのかな?と思う瞬間が人生の中であったり、なかったり)
9:デフォルトの名無しさん (ワッチョイ 297c-tLJy)
23/11/01 12:51:50.53 h0xHi7n60.net
(礼儀とプログラミングスキルは関係ないと思う)
10:デフォルトの名無しさん (ワッチョイ 13ad-feYx)
23/11/01 12:53:02.45 c3s+uM8y0.net
(俺の昼飯どこ行った?)
11:デフォルトの名無しさん (アウアウウー Sad5-U1R4)
23/11/01 16:02:16.42 G1jsC9Xya.net
(今日の昼飯はセブンのサバ塩焼弁当にしとくか・・・)
12:デフォルトの名無しさん (ワッチョイ 1939-PupP)
23/11/01 18:24:49.00 m9AntJVX0.net
コードにはある程度そいつの人間性は反映されるな
スレチな話題ではあるけど
13:デフォルトの名無しさん
23/11/01 23:07:31.46 PfaqlzcX0.net
(本物のプログラマはPascalを使わない)
14:デフォルトの名無しさん
23/11/01 23:30:59.94 ZqfN6pKA0.net
(でもPythonは使ってもいいのかな?って時々思う)
15:デフォルトの名無しさん
23/11/02 00:03:32.45 aqkFofyNM.net
そろそろキャストは止めてスマポ使いましょう
16:デフォルトの名無しさん
23/11/02 02:43:15.24 +4XO/JeH0.net
まちゅまちゅの3Dライブみた
前も思ったけどみこちとかなたそのダンス、めっちゃシンクロ率高い
リズムがぴったり一緒なんだよね
ダンスほんとにうまくなったよな
17:デフォルトの名無しさん
23/11/02 02:43:45.89 +4XO/JeH0.net
誤爆った(´・ω・`)
18:デフォルトの名無しさん (ワッチョイ 1bda-9b8G)
23/11/02 07:17:03.35 Hn8AmdCQ0.net
ホロライブか
19:デフォルトの名無しさん (アウアウウー Sad5-U1R4)
23/11/02 10:44:27.02 BqsrFUCWa.net
(まちゅまちゅの3Dライブ?・・・ちょっと気になる)
20:デフォルトの名無しさん
23/11/02 23:48:48.29 ebj85xCu0.net
(((お前ら括弧ばっかり使ってlisperかよ?)))
21:デフォルトの名無しさん
23/11/03 10:21:23.72 sUQ44pbr0.net
←vーー( ゚∀゚)!ー^ー
22:デフォルトの名無しさん
23/11/04 18:56:36.20 Y/q1DSa/0.net
コピーとムーブの挙動、というか管理難しい。。難しくない?
23:はちみつ餃子
23/11/04 20:24:08.34 1CTu6tq50.net
コピーやムーブはパターンに沿って管理できるからそんなに難しいとは感じないな。
ワイとしては参照の畳み込み (Reference collapsing) や変換の規則を毎回のように確認するんだけど全然頭に入ってこない。
参照はオブジェクトではないので逆に言えば値に対応する型が参照になることはないのだが、それはそれとして参照を含む型があり得るというのが今でも腑に落ちない。
24:デフォルトの名無しさん
23/11/04 20:28:09.97 KOZ2F//lM.net
参照しか知らんものだけど、ムーブて何か簡単に教えて
参照は実装上ただのポインタじゃん
ムーブはなにがどうなるん?
25:はちみつ餃子
23/11/04 20:29:19.85 1CTu6tq50.net
ムーブコンストラクタが起動する。
それだけ。
26:デフォルトの名無しさん
23/11/05 09:49:50.04 6vgG9vCb0.net
>>24
考え方としては、shallow copyを二重開放リスクを避けて行うための仕組み。
右辺値という特別な一時変数のコピーで特別なコピー(ムーブコンストラクタ)を実行するようにして、クラス設計者が必要に応じてshallow copyを実装しやすくしている。
27:デフォルトの名無しさん
23/11/05 10:41:04.16 ol9bMVcca.net
>>24
moveはRustで言う所有権の移動じゃないか
28:デフォルトの名無しさん (ワッチョイ 454e-0SSA)
23/11/05 13:06:56.97 Qkn7cpbH0.net
>>24
aに戻り値などの一時オブジェクトbをコピーすると通常は
aでメモリを確保
bからメモリコピー
bのデストラクタでメモリを破棄
という動作になるけど、moveの場合
aにbでメモリをポインタで持ってくる
bのインスタンスでは破棄したことにする
とすれば無駄なメモリ確保とコピーが発生せず効率が良い
29:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 823e-9NWm)
23/11/05 13:39:42.02 pHGS9osC0.net
標準ライブラリでのムーブは所有権 (ownership) の概念を前提として構築されているし、
慣例としてもそのようにするものではあるんだが
言語としてはムーブコンストラクタ (またはムーブ代入演算子) を呼び出すというだけで
所有権の面倒をみる機能は何もない。
(辻褄が合うようにするのはプログラマの責任。)
何が起きているのかは所有権の概念と実装レベルで分けて考えたほうがいいと思う。
どう説明していいかわからんから関連する要素を箇条書きにしたらこんな感じかな。
・ それがコピーの文脈であるかムーブの文脈であるか区別は出来る
・ 一般的にムーブの文脈であった場合 (寿命が尽きる直前の一時オブジェクトの再利用が出来る場合) にコピーより効率が良い動作が出来る可能性がある
・ どのように効率がよくなるのかはそのクラス (のムーブコンストラクタやムーブ代入演算子) の定義次第
・ 典型的なムーブの実装はリソース本体を指すポインタの交換によって実現される
・ ユーザーが定義を与えなかった場合のデフォルトのムーブは全てのサブオブジェクトをムーブすることになっている
30:デフォルトの名無しさん (ワッチョイ 454e-0SSA)
23/11/05 13:42:20.39 Qkn7cpbH0.net
で、このmove動作を定義するために、
一時オブジェクト(右辺値)に対する参照動作を関数定義できるようになっている
31:デフォルトの名無しさん (ワントンキン MM92-JcAe)
23/11/05 14:05:22.83 wAmDr/fyM.net
ムーブされるとそのポインタは変わってしまうと思うけど、そういうケースはないの?
32:デフォルトの名無しさん (ワッチョイ 454e-0SSA)
23/11/05 14:18:09.07 Qkn7cpbH0.net
言っている意味がよく分からないが、純粋なポインタにはムーブという概念はないよ
ムーブを定義できるのはクラスに対してだけ
他の人も言っているようにムーブといっても実体は単なる関数呼び出しなので、その中でプログラマが自分の責任で必要なコードを書くことになる
33:デフォルトの名無しさん (ワッチョイ 653d-2MVi)
23/11/05 14:58:05.35 vIwIC4VV0.net
質問した人じゃないけど説明ありがたいです
ムーブ難しいと思ってたけどもっと早く勉強して仕事で使うべきだった
(文法解析した要素をポインタいじって並べ変えるんだけど…
二重所有を防ぐのを手作業コーディングで責任を持たなければならないプログラムを作ってしまった)
34:デフォルトの名無しさん (ワッチョイ 454e-0SSA)
23/11/05 15:15:28.75 Qkn7cpbH0.net
ただ、右辺値参照を使うと、通常の参照や代入と使い分けるためにconstやnoexceptを厳密に指定しないといけなくなりがちだから、
その辺の総合的な理解が必要になってくるのは注意点だね
constは一度付け始めるとライブラリ全部に伝染するからな・・・それを嫌って使わない派も結構いる(いた)よね
35:デフォルトの名無しさん (ワッチョイ ed7c-9LC0)
23/11/05 15:39:17.77 Vx5ySS520.net
実際のコードだとポインタのムーブはunique_ptrとかにぶん投げで、自分で移動コード書くことはまずないな
自分でムーブ特殊関数の中身書くのはハンドル的なもののムーブを実現したいときくらい
36:デフォルトの名無しさん
23/11/05 16:12:35.07 jiV3XvQ2a.net
とにかく unique_ptr が便利すぎるから何でもかんでも全部 unique_ptr 使うようになってしまった
まあそれでいいのかもしれないが
37:デフォルトの名無しさん
23/11/05 16:21:29.02 ol9bMVcca.net
>>33
銀の弾丸ではない
手作業コーディングで責任を持たなければならないのは変わらない
38:はちみつ餃子
23/11/05 17:10:59.04 pHGS9osC0.net
所有権管理も結局はプログラマが書く (間違いを部分的にコンパイルエラーとして検出できることはある)、
所有権って具体的に何なんだってのはクラス定義に押し込めるという風に管理のレイヤを分けることが出来るってわけ。
クラス定義をした後は具体的に何をやってるのかを忘れて
所有権というものだと思い込むことが出来るという抽象化の仕組み。
39:デフォルトの名無しさん
23/11/07 10:10:32.04 5c9945xO0.net
>>37
アホか
普通に考えて、そのコード(クラス)の利用者が所有権について明示的に何かしなきゃいけなかったということだろ
40:デフォルトの名無しさん
23/11/07 19:02:58.77 Z7KocuHY0.net
>>33
エスパーするけど多分その用途だとmoveは使えない。
データを共有している感じなので素直にshared ptrを使うのがいいかと。shared ptrで性能的にキツイならshared ptrを参照渡しするか。
41:デフォルトの名無しさん
23/11/07 19:09:56.10 Z7KocuHY0.net
>>40
ちょっと補足すると、戻り値をshared ptrの参照にするのはNGですな。そこは素直にRVOに期待するのが良いか。
42:デフォルトの名無しさん
23/11/09 17:23:48.54 Op1F6lz40.net
VC++なんだけど32bitで_thiscallを関数ポインタ経由で呼ぶことってasm使わないと不可能?
メンバ関数を関数ポインタ変数とすることは出来てもそこから第一引数にインスタンス入れたりしてもコンパイル時エラーになる
43:デフォルトの名無しさん
23/11/09 18:09:02.18 vDu6brxv0.net
>>42
メンバ関数をポインタ経由で呼び出したいってことならstd::bindでできるはず
44:はちみつ餃子
23/11/09 18:24:20.63 viBVvDAP0.net
VC++ のことは知らんけどメンバ関数ポインタは関数ポインタより大きい実装になってる処理系がある。
メンバ関数ポインタを関数ポインタに変換した時点で呼び出すのに必要な情報が失われているかもしれない。
45:デフォルトの名無しさん
23/11/09 19:04:30.42 YhbH7ApDM.net
MJD?
46:デフォルトの名無しさん
23/11/09 19:13:19.18 RZ9WOZDMM.net
エラーメッセージにヒントはない?
47:はちみつ餃子
23/11/09 19:58:26.06 u3KRHVuW0.net
基本的には言語の規定内でやるに越したことはないので無理な型変換をしないで済ませられるように出来るものならそうしたほうがいい。
どうしてもそうできない事情がある(と質問者が認識している)ならもうちょっと詳しい状況をコードで示して欲しい。
48:デフォルトの名無しさん (ワッチョイ e5a7-cSrA)
23/11/09 21:12:03.97 Op1F6lz40.net
>>43
ありがとう、逆アセ見たら完璧にthiscallになってた
メンバ関数っていうかthiscall指定したものは32bitだとecxレジスタにthisポインタが隠されていてそれ以外はstdcallと同じ
なので下みたいに第一引数にインスタンスのポインタを入れる事でecxに代入される感じになりそうだなーと思ったら無理だった
ちなみに64bitの場合はどちらもfastcallで同じだから単純に第一引数にthisポインタが隠されてるだけ
auto pFunc = CDate::addDay; // CDate addDay(int value)
CDate tomorrow = pFunc(&instance, 1);
49:デフォルトの名無しさん (ワッチョイ e5a7-cSrA)
23/11/09 21:28:58.67 Op1F6lz40.net
てかググったら簡単なシミュレーション方法載せてるブログあった
_fastcallで宣言して第二引数のedxを捨て駒にする事で疑似_thiscallになる
つまりint(__fastcall * pFunc)(CDate*, void*, int)とすれば一応アセンブラ的な辻褄は合う事になる
50:デフォルトの名無しさん
23/11/12 10:07:59.74 j2Y95IYf0.net
質問なのですが型Tの参照を返す関数 const T& foo() の戻り値をautoのいくつかのバリエーションで受けてアドレスを見て見たのですが
auto x = foo();
auto& y = foo();
const auto z = foo();
const auto& zz = foo();
const volatile auto& zzz = foo();
cout << "&original=" << &g_vec << endl; // &original = 00B013D8 (このアドレスは一例)
cout << "&x=" << &x << endl; // &x = 010FF8AC // コピー(意図しないかも?)
cout << "&y=" << &y << endl; // &y = 00B013D8 // 参照(OK)
cout << "&z=" << &z << endl; // &z = 010FF888 // コピー(意図しないかも?)
cout << "&zz=" << &zz << endl; // &zz = 00B013D8 // 参照(OK)
cout << "&zzz=" << &zzz << endl; // &zzz = 1 // !!!!
という行末コメントに記載の結果になったお
Q1. 参照で受けたい場合は auto でなく auto& とせねばならない、で正しい?
Q2. 間違えてauto で受けても動いてしまい発見し難いケースが多いと思うのですが
意図しないパフォーマンス低下になるので防ぐ対策とか無い?
Q3. zzzのアドレスが1になるのは一体……
MSVC2019使用、言語の設定はC++14、
51:はちみつ餃子
23/11/12 11:02:37.63 O0gb6uIB0.net
>>50
A1. 単に auto としたときに参照になることはない。
参照として受け取りたい場合は auto& にせねばならないというのは正しい。
A2. 参照かどうかで自動的に場合分けして欲しいなら decltype(auto) とすればいいが……
参照で受けるのが正しい状況なのかどうかは状況による。
テンプレート内など自動的な場合分けが必要な場合を除いては参照は参照として明示したほうがよくない?
(個人的感想です。)
A3. いくつか用意されている operator<< の基本的なオーバーロードの内で bool にマッチするから。
void* もあるのだけれど C++ では任意のポインタは void* へは暗黙の型変換されないのでマッチング候補にならない。
アドレスとして解釈して欲しいなら void* へ明示的に型変換しないといけない。
52:はちみつ餃子
23/11/12 11:38:27.18 O0gb6uIB0.net
ごめん。 間違いがあった。
ポインタは void* へ暗黙に変換できる。
この変換はオーバーロード解決時の候補になりうる。
ただ、 bool への変換とは優先順位に差がある。
53:デフォルトの名無しさん
23/11/12 11:42:25.19 j2Y95IYf0.net
>>52
㌧クス、
なるほど
わかりた
↓こうなったわ
decltype(auto) z = foo();
const auto& zz = foo();
const volatile auto& zzz = foo();
cout << "&original=" << (void*)&g_vec << endl; // &original=010213D8 (このアドレスは一例)
cout << "&z=" << (void*)&z << endl; // &z=010213D8 // 参照(OK)
cout << "&zz=" << (void*)&zz << endl; // &zz=010213D8 // 参照(OK)
cout << "&zzz=" << (void*)&zzz << endl; // &zzz=010213D8 // 参照(OK)
cout << std::boolalpha << "&zzz=" << &zzz << endl; // &zzz=true // boolean
boolへの変換は使うことは無いと思うが正体は調べてみるわ
54:デフォルトの名無しさん
23/11/12 11:46:29.61 j2Y95IYf0.net
>テンプレート内など自動的な場合分けが必要な場合を除いては参照は参照として明示したほうがよくない?
非constなら考えるがこの場合foo()はconstオヌジェクトと参照を返してくるし、
これはもうdecltype(auto)一択で良いような気がが、
55:はちみつ餃子
23/11/12 12:07:32.76 O0gb6uIB0.net
volatile を追加する変換は出来るが除く変換は出来ないから
volatile 付きのオーバーロードを用意していない operator<< では候補から消えて
bool だけが候補として残ってしまうってことになるみたいだな。
volatile が付いていない場合は
void* への変換のほうが bool への変換より優先順位が高いので
そっちが呼ばれる。
56:デフォルトの名無しさん (ワッチョイ 1fcc-mzjy)
23/11/13 00:27:59.42 G429czY+0.net
Tiktok LiteでPayPayやAmazonギフトなどに交換可能な4000円分のポイントをプレゼント中!
※既存Tiktokユーザーの方はTiktokアプリからログアウトしてアンインストールすればできる可能性があります。
1.SIMの入ったスマホ・タブレットを用意する
2.以下のTiktok Liteのサイトからアプリをダウンロード(ダウンロードだけでまだ起動しない)
URLリンク(lite.tiktok.com)
3.ダウンロード完了後、もう一度上記アドレスのリンクからアプリへ
4.アプリ内でTiktokで使用してない電話番号かメールアドレスから登禄
5.10日間連続チェックインで合計で4000円分のポイントゲット
ポイントはPayPayやAmazonギフト券に交換可能!
家族・友人に紹介したり通常タスクをこなせば更にポイントを追加でゲットできます。
57:デフォルトの名無しさん
23/11/13 02:33:43.38 eLF59GiN0.net
>>56
案内サンクス
58:デフォルトの名無しさん (ワッチョイ 1f01-XI6K)
23/11/14 02:19:13.60 DkCdWP9x0.net
CLion使ってる人いますか?
59:デフォルトの名無しさん (ワッチョイ 1fad-XI6K)
23/11/17 17:16:02.48 TT3SJP5h0.net
日本人の死亡者が増えてるのに、メディアは報道規制
スレリンク(cafe50板)
sssp://o.5ch.net/224t1.png
60:デフォルトの名無しさん (ワッチョイ 6ecf-ekUX)
23/11/18 16:16:09.27 5MckQHFy0.net
ラムダの参照キャプチャってconst参照に指定できないんだっけ?微妙に不便だな。
61:デフォルトの名無しさん
23/11/18 20:47:45.62 GRi2RJZB0.net
>>60
これじゃだめ?
#include <iostream>
using namespace std;
int main () {
const int a {0};
int b {0};
[&a, &b = const_cast <const int &> (b)] () {
++ a; // X
++ b; // X
} ();
return 0;
}
62:デフォルトの名無しさん
23/11/26 06:27:21.37 DSb557XU0.net
C++20 RangesはMicrosoftの説明がわかりやすかった
63:デフォルトの名無しさん
23/12/05 10:33:06.64 HLoKrA0o0.net
ふと今更思ったんだけど
ポインターpに対して演算子*が返す*pは、
値じゃなくて参照?
64:デフォルトの名無しさん
23/12/05 11:05:15.15 E3GJtsiR0.net
#include <type_traits>
#include <iostream>
using namespace std;
int main () {
int value {0};
int *p {&value};
cout << is_reference <int>::value << '\n';
cout << is_reference <int &>::value << '\n';
cout << is_reference <decltype (value)>::value << '\n';
cout << is_reference <decltype (*p)>::value << '\n';
return 0;
}
65:デフォルトの名無しさん
23/12/05 11:09:19.91 IVr4NrBA0.net
>>63
参照ってのが何を意味しているか分からんが
普通はポインターの示す場所の内容だ
66:はちみつ餃子
23/12/05 11:22:18.93 z5PiblaY0.net
>>63
ポインター p に対して *p とした場合の型は参照ではない。
たぶん >>64 は *p が参照と言いたいつもりで書いているんだと思うけど
decltype に与えられる式の型が T 型の lvalue だった場合には T& が返されるルールなので
その式が参照でなくても参照が返されることがある。
67:はちみつ餃子
23/12/05 11:24:42.01 z5PiblaY0.net
あ、ごめん。 完全に間違った説明してたわ。 忘れて……。 恥ずかしい。
68:はちみつ餃子
23/12/05 11:34:00.06 z5PiblaY0.net
と思ってよく仕様を読んでみたらやっぱりこの (>>66) 考え方で正しいはず。
式が識別子式の時に限っては decltype は参照にならず式の型そのままで返すせいで decltype(value) は参照にならないが、
value と *p は型システム的にも値カテゴリ的にも同じだわ。
69:デフォルトの名無しさん
23/12/05 12:43:28.97 E3GJtsiR0.net
>>68
なるほどー! 横からだが勉強になった
70:デフォルトの名無しさん
23/12/05 12:48:03.77 E3GJtsiR0.net
巷のスマートポインタはoperator*で参照型を返すので
生ポインタも同じかと思ってたよ
71:はちみつ餃子
23/12/05 13:28:25.92 z5PiblaY0.net
互換性の都合とかがあるから仕方ないね。
場合分けが大量にあって単純な一般原則の組み合わせにはなってないから仕様を読み解くのがしんどい……
72:デフォルトの名無しさん
23/12/11 15:17:51.77 7vxydTfj0.net
ある構造体Aがあります
Aの比較関数が複数ありますcompA0,compA1,compA2,...
比較関数の関数ポインタがありますcompA
compA = &compA2;
別の構造体Bがあります
BはAを内包しています
struct B{ A a; ... };
この構造体Bを、Aの比較関数ポインタcompAで比較してソートするにはどう記述すればよいですか?
std::vector<B> bs;
bs.push_back(...);...
std::sort(bs.begin(),bs.end(),?);
できればラムダ式を使わずにできるとありがたいです
73:デフォルトの名無しさん
23/12/11 15:22:02.06 F1R6HyeLM.net
>>72
ラムダ式使った方が良いと思うけど本当にラムダ式なしが良い?
74:デフォルトの名無しさん
23/12/11 15:29:19.94 7vxydTfj0.net
使われると、ラムダ式の質問をすることになると思います・・・
75:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-pD6R)
23/12/11 15:45:20.57 wAhsIAfi0.net
>>72
もし C++20 を使えるなら (std::sort と違って) std::ranges::sort では比較関数とは別に
比較すべき要素を取り出す操作をプロジェクションとして与えることが出来るから
これ一発でいけてだいぶん楽できる。
std::ranges::sort(bs, compA, &B::a);
76:デフォルトの名無しさん (ワッチョイ d701-Qbcu)
23/12/11 16:01:10.52 dil4ai7q0.net
>>75
すげ! 今そんなのあるんやね
77:デフォルトの名無しさん
23/12/11 16:34:20.59 dil4ai7q0.net
>>74
思い出すのがしんどくなってきた
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
struct A {int value_;};
bool compA2 (const A &lhs, const A &rhs) {
return lhs.value_ < rhs.value_;
}
struct B {A a;};
int main () {
vector <B> bs;
bool (*compA) (const A &, const A &) {compA2};
sort (bs.begin(), bs.end(), bind (compA, bind (mem_fn (&B::a), placeholders::_1), bind (mem_fn (&B::a), placeholders::_2)));
sort (bs.begin(), bs.end(), [compA] (const auto &lhs, const auto &rhs) {return (*compA) (lhs.a, rhs.a);});
return 0;
}
78:デフォルトの名無しさん
23/12/11 17:14:54.00 cVrrslE50.net
>>75
>>77
お二方、ありがとうございます
参考にして組んでみます
79:はちみつ餃子
23/12/11 17:25:04.51 wAhsIAfi0.net
その場で合成するのはさすがに見通しが悪すぎるので、
C++11 頃の C++ を仮定して私がやるならまずアダプタを作ると思う。
ちょっと雑ですまんがとりあえずこんな感じ。
class compB_adaptor {
private:
using comparator = std::function<bool(const A&, const A&)>;
comparator compA;
public:
compB_adaptor(comparator comp) : compA(comp) {}
bool operator()(const B& x, const B& y) {
return compA(x.a, y.a);
}
};
使うときには間にひとつ挟むだけで済む。
std::sort(bs.begin(), bs.end(), compB_adaptor(compA));
80:デフォルトの名無しさん (ワッチョイ 771f-oseA)
23/12/11 22:08:32.24 cVrrslE50.net
>>79
求めていたものそのものであったため、採用させていただきました
ありがとうございます
81:デフォルトの名無しさん
23/12/20 23:47:12.14 tqHuIeXr0.net
int x;
std::cout << x;
でxが正ののときは「+」符号を付けさせるのってどうするんでしたっけ……
cout.form("%+d", x)とか以外で
82:デフォルトの名無しさん
23/12/20 23:58:48.32 Qfvbx0VO0.net
cout << showpos
83:デフォルトの名無しさん (ワッチョイ 1663-4if3)
23/12/21 08:41:44.38 6wjPSKlj0.net
てきました㌧クス、
iosヘッダで探せば良かったのか、、、
84:デフォルトの名無しさん
23/12/21 20:01:46.13 i16TeC3D0.net
C++23だとこれ
std::print("{:+}", x);
85:デフォルトの名無しさん
23/12/22 13:56:54.85 pQLEje080.net
PythonやC#のようなf"{x}"構文が作られる事はないんだろうか
86:はちみつ餃子
23/12/22 14:54:27.15 gr/vrzoo0.net
>>85
リフレクションが充実すればその上に実装できるので
直接的な言語機能として用意すると
辻褄合わせが後で面倒になるだろうし、
現時点で考えるのは時期尚早だと思う。
87:デフォルトの名無しさん
23/12/24 17:42:14.24 foDTiHm90.net
質問なのですが自作クラスFooのストリーム出力演算子に引数付きのマニピュレータを追加したいのですが
↓こんなやつ
Foo obj;
cout << custom_setw(10) << obj; // 整数のベクトル的なオブジェクトobjの要素を幅10文字で出力
custom_setw()で与えた10という数値をつつがなくFooのストリーム出力演算子
std::ostream& operator<<(std::ostream& os, const Foo& obj)
に渡すには一体どうすれば……orz
88:デフォルトの名無しさん
23/12/24 17:42:52.36 foDTiHm90.net
グローバル変数渡しは最初に思いつくのですが、ostringstream os1, os2とFoo obj1, obj2に対して異なるスレッドで
os1 << custom_setw(30) << obj1; // スレッド1
os2 << custom_setw(20) << obj2; // スレッド2
とかやったら詰むし
std::setw()とか一体どうやってるんじゃ……
89:はちみつ餃子
23/12/24 18:05:55.09 SfA3xmSz0.net
>>87-88
特定の型を出力するときにだけ作用する書式を設定するマニピュレータってこと?
std::setw がやってるのはストリームのメンバ関数 width を呼ぶのと同じ。
ストリームのオブジェクトが幅に関する情報を保存するデータメンバを持っていて、それを変更してる。
もちろんあなたが定義した独自の型 (この例では Foo) に結び付いた書式を保持するところなんて存在しないから単純にはできない。
私が思いつくのは
・ ストリームのほうも新しいものを定義する、つまり basic_ostream を継承して Foo 用の書式を格納するデータメンバを増やす
・ ストリームに対応付いたデータを格納するものを std::map かなんかで保持しておいて Foo を出力するときはそれを参照する
ということくらいかな。
スレッドが絡むと面倒くさいけど、しょうがないね。
90:デフォルトの名無しさん
23/12/24 19:04:41.48 vbUOIudY0.net
既存のcoutとかstringstreamとかで使いたいなら、グローバルのstd::unordered_map<std::ios_base*, MyManipData>にでも置いとくしかないだろうね
ストリームオブジェクトの状態で持たせるクソ設計が悪いんだ
91:デフォルトの名無しさん
23/12/24 19:34:37.93 foDTiHm90.net
レス㌧クス、
>ストリームのオブジェクトが幅に関する情報を保存するデータメンバを持っていて、それを変更してる。
なるほど……
これはユザーの立場からはメンバの追加ができない領域なので、Fooの側にメンバを持たせることにしますか……
class FooWrp {
const Foo& m_objRef;
int m_nWidth;
public:
FooWrp(const Foo& obj, int width) : m_objRef(obj), m_nWidh(width) { }
friend std::ostream& operator<<(std::ostream& os, const FooWrp& wrp) { ...(wrp.m_objRefの要素をwrp.m_nWidthに描かれている幅で出力する処理)... }
};
92:デフォルトの名無しさん
23/12/24 19:35:17.01 foDTiHm90.net
// 使い方
Foo obj;
cout << FooWrp(obj, 10);
ダッサwwwwwwwwwwwwwwwwwww
しかし、「たかが表示の整形」のために排他制御しつつmapを弄ったりTLSの利用を考えるのもアレなのでこれはこれで仕方が無いのか、orz
93:デフォルトの名無しさん
23/12/24 19:45:29.51 Y8qSN/i/0.net
ストリーム用の演算子なんか作らずに
オブジェクトの文字列表現を返す関数を用意したほうが汎用性高くない?
94:デフォルトの名無しさん
23/12/24 19:50:06.00 foDTiHm90.net
Foo obj;
std::string s = obj.str(10); // 10億ギガ文字
cout << s;
出力を完遂できるんかこれ……
95:はちみつ餃子
23/12/24 20:00:55.29 SfA3xmSz0.net
C++20 からは std::formatter を特殊化して書式指定を解釈するコードを入れておけば
std::format で独自の型を表示しようとしたときにその特殊化が使われる仕組みになってる。
96:デフォルトの名無しさん
23/12/24 21:41:50.00 Y8qSN/i/0.net
オブジェクトの文字列表現が10億ギガ文字もあるの!?
FooWrpオブジェクトをうっかりログに出力しちゃったら大変だね!!
97:デフォルトの名無しさん (ワッチョイ cf63-nyJS)
23/12/29 19:34:46.18 MPSeCS+O0.net
実験せずに質問するますが、
int a, b;
cin >> &x >> &y;
に対し、
Q1. 「100 a」を入力したら例外もタイムアウト待ちも発生せず、cin.fail()がtrueになるだけ?
Q2. 「100」とだけ入力してそのまんま(リダイレクト元のファイルハンドルか何かが
タイムアウトもエラーもクローズもしなければ)ならそれっきり返ってこない?
98:デフォルトの名無しさん (ワッチョイ cf63-nyJS)
23/12/29 19:40:39.84 MPSeCS+O0.net
EOFが抜けてたorz
Q2のケースにおいて「100 [EOF]」なら(多分)cin.fail()でとりあえずすぐ返ってくるのかそうか、
99:はちみつ餃子
23/12/29 21:37:06.10 0cvltfsQ0.net
>>97
実にしょうもない確認なんだけど、
言いたいことは
int x, y;
cin >> x >> y;
でよいんだよね?
100:デフォルトの名無しさん (ワッチョイ de63-J7+h)
23/12/30 05:42:41.89 3ksfrMrT0.net
>>99
>int x, y;
>cin >> x >> y;
おk
スマンカッタorz
エラーとEOFのどちらかを検知したかったら!cin.good()が正しいっぽい?
URLリンク(blog.emattsan.org)
ここまでは分かった気がするが、
ストリーム入力演算子std::istream& operator>>(std::istream& os, Foo& obj)の中で入力に失敗した場合
どうやってエラーを呼び出し元に通知したらええんじゃ……
101:デフォルトの名無しさん
23/12/30 05:50:37.02 3ksfrMrT0.net
クラスFooの入力ストリーム演算子の中で整数を2個読むとして、
std::istream& operator>>(std::istream& os, Foo& obj) {
int x, y;
os >> x >> y;
if (!os.goot()) {
return os; // エラー発生時は単純にreturn os; でおk?
}
obj.m_x = x;
obj.m_y = y;
return os;
}
102:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 43c3-KM86)
23/12/30 08:47:16.28 XV37Te4m0.net
>>100
ストリームのフラグを立てるメンバ関数は setstate だけど
>>101 の状況ならフラグはもう立ってるから戻るだけで問題ないよ。
103:デフォルトの名無しさん
23/12/30 13:48:41.88 3ksfrMrT0.net
わかりた
ていうかエラー判定(eofbit以外のビットのセットを判定)なら!os.good()や!os.goot()ではなくて
os.failed()か!osですたね……orz
これらに関して追加の質問が出たら初心者スレに書くわサーセン;;;
104:デフォルトの名無しさん
23/12/31 20:09:05.68 tpduSr4A0.net
class A{
char buf_[size];
}
このbuf_に任意のオブジェクトをplacement newして使用するのだけど
このオブジェクトをコピーしたりムーブする場合、単純にコピー元のbuf_からコピー先のbuf_にmemcopyしてしまって大丈夫ですか?
105:デフォルトの名無しさん
23/12/31 20:44:02.18 bvEcnWMM0.net
全く大丈夫じゃない
初心者スレからどうぞ
106:デフォルトの名無しさん
23/12/31 20:54:11.90 NNsdlVTY0.net
構造体から派生させれば出来るよ
107:デフォルトの名無しさん
23/12/31 21:04:16.47 bvEcnWMM0.net
せめてPODと言おう
初心者スレからどうぞ
108:はちみつ餃子
24/01/01 00:18:02.48 6hyMwo3D0.net
POD は削除された。
trivially copyable の要件を満たすならその型は memcpy でコピーしてもよい。
std::is_trivially_copyable で判定できるのでどこかに制約を入れておけば安心かもね。
109:デフォルトの名無しさん
24/01/01 00:36:03.09 an53Mx2V0.net
削除されたんですか?(バージョンいくつで?)
c++20 で非推奨になった、てのはすぐ調べられたんだけどその先が分からんです
110:はちみつ餃子
24/01/01 00:46:07.42 6hyMwo3D0.net
>>109
規格の文面としては C++20 で POD はもう削除されていて POD の概念を使わない形で再編されてる。
std::is_pod はまだある (非推奨) からこれが POD の定義だという意味ではまだあるとも言えるけど。
111:デフォルトの名無しさん
24/01/01 00:46:34.65 l/ylj5kb0.net
アライメント忘れてるぞ
112:デフォルトの名無しさん (ワッチョイ e1f0-JZT3)
24/01/01 03:01:35.02 5pNbZa2B0.net
>>104
まず自分でコード書いてみ
よろしくないところは指摘してやるから
113:デフォルトの名無しさん (ワッチョイ 8101-KEYj)
24/01/01 03:14:22.37 8zoq4UeO0.net
オワコン名称出してマウント。プークスクス
114:はちみつ餃子
24/01/01 03:40:47.98 hmX3WjmM0.net
POD が削除されたかどうかは重要ではなくて、 POD より弱い制約 (trivially copyable) で memcpy が許されるというのが主旨。
その点は C++11 からそうなってる。
115:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 823e-OTTg)
24/01/01 04:06:49.46 hmX3WjmM0.net
「構造体」ってのも C++ 用語的にはイケてないと思うよ。
116:デフォルトの名無しさん
24/01/01 04:55:26.71 e5pnn2Xx0.net
アライメントは基本型のどれかと同じアライメント制約に合わせれば良いいということなら
使おうとしているうちで最も厳しいアライメント制約に一致する基本型を含むunionで解決するというのがC言語における伝統的な手法という印象、
C++でunionにしたら(それが可能なメンバのみなら) memcpyは安全とかにはならない?
117:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 823e-OTTg)
24/01/01 05:30:52.12 hmX3WjmM0.net
>>116
コンストラクタや代入演算子がトリビアルであることなどの制約を守れば共用体も trivially copyable になりうる。
(C++ の共用体はコンストラクタやメンバ関数を定義できるがそこらが制限されることになる。)
118:デフォルトの名無しさん
24/01/01 14:24:55.17 kge3DGj60.net
char* と long* のコピーは?
119:はちみつ餃子
24/01/01 15:31:30.97 hmX3WjmM0.net
ポインタも含めてスカラ型は Trivially copyable
URLリンク(timsong-cpp.github.io)
120:デフォルトの名無しさん
24/01/03 23:34:38.84 w4EAqTeZ0.net
>>112
とりあえず書いてみたけどどうですかね?
template<std::size_t buf_size>
struct A {
private:
struct base_ {
virtual ~base_() {};
};
template <typename F>
struct derived_ : base_ {
F f_;
derived_(F f) : f_{ std::move(f) } {}
};
base_* p_;
alignas(alignof(std::max_align_t)) uint8_t buf[buf_size]={0};
public:
A() :p_(nullptr) {};
template <typename F>
void assign(F f) {
if (p_ == nullptr) {
p_ = ::new (buf) derived_<F>{std::move(f)};
}
}
//コピーコンストラクタ
A(A& src) {
p_ = ::new (buf) decltype(src.*p_); //ここが怪しい
};
};
121:デフォルトの名無しさん
24/01/04 00:44:07.87 /FDyuY0i0.net
decltype(src.*p_)ってbase_なのでダメだろう
122:デフォルトの名無しさん
24/01/04 00:58:18.81 ECF9R1Fj0.net
ていうか、decltypeで型指定してるだけだからコピーもなにもされてないぞソレ
123:デフォルトの名無しさん
24/01/04 02:28:40.49 oZapr/U70.net
std::anyのコードでも読んだほうが早い
124:デフォルトの名無しさん
24/01/04 09:11:56.12 /FDyuY0i0.net
A::base_に以下を足してA::derived_で実装し
Aのコピーコンストラクタから呼べば?
virtual base_ *clone (void *p) = 0;
125:デフォルトの名無しさん
24/01/04 13:26:37.40 1KQpMTCj0.net
void*って、ポインターの先のサイズ未知だよなぁ
126:デフォルトの名無しさん
24/01/04 17:16:40.43 ACseOt7T0.net
derived_かそのメンバf_の型を知るにはRTTIしかないのですかね?
>>121
decltypeだと派生先の型はわからないのか
>>122
実体のコピーの処理が抜けてました…
127:デフォルトの名無しさん
24/01/04 21:53:05.60 ACseOt7T0.net
>>124
こんな感じです?
struct base_ {
virtual base_* clone (void *p) = 0;
virtual ~base_() {};
};
template <typename F>
struct derived_ : base_ {
F f_;
derived_(F f) : f_{ std::move(f) } {}
base_* clone (void *p_buf){
return new(reinterpret_cast<derived_<F>*>(p_buf))(f_);
}
};
A(A& src) {
p_ = src.clone((void*)buf);
};
128:デフォルトの名無しさん
24/01/04 22:19:16.70 ECF9R1Fj0.net
derived_(F f) ←この時点でムダなコピーが1度発生していることには気付いてる?
129:デフォルトの名無しさん
24/01/04 22:21:15.81 /FDyuY0i0.net
>>127
書き込む前にコンパイルしなよ
130:デフォルトの名無しさん
24/01/04 22:41:26.61 Dv09vJ7A0.net
バッファの中にオブジェクトを作れたら、それで何をしたいのかが気になる
131:デフォルトの名無しさん
24/01/04 23:21:36.86 oZapr/U70.net
>>127
cloneの中ってplacement newでcopy constructorを呼ぼうとしてるんだよな?
いちおうあってるけどundefined behaviorまみれ
132:はちみつ餃子
24/01/04 23:35:27.70 td6kYpbC0.net
たぶんやりたいことは std::allocator_traits::construct なのかな
133:デフォルトの名無しさん (ワッチョイ 7f7c-JApz)
24/01/11 04:45:44.72 wlSOhq+Y0.net
例外って全部mainで捕捉すべきかな?
調べてみたら例外が捕捉されずにプログラムが終了する場合スタックアンワインドが起こるかは実装定義みたいなんだけど、それじゃグローバルなオブジェクトのデストラクタが呼ばれないんじゃないかって思って試してみたのよ。
URLリンク(ideone.com)
やっぱりデストラクタは呼ばれなかったからリソースリークが起こりうるんじゃないかと思うんだけど、例外に対してはどういう態度でいるべきかな?
A. リソースリークはまずい。だから例外は全部捕捉するべき。
B. 例外はロジック上捕捉する必要があるものだけ捕捉して、それ以外はほっといていい。
C. 例外が捕捉されなければstd::abortが呼ばれるので、コアダンプなりで色々調べることもできる。だからmainで例外を全部握りつぶすようなことはすべきではない。
D. 時と場合による。
例外時の挙動とか仕様とか調べてるうちに頭ぐるぐるしてわけわかんなくなってきた
134:デフォルトの名無しさん
24/01/11 08:40:16.50 8oRrkiTZ0.net
そもそもプログラムが終了してリソースリークするのかな?
メモリー、ファイルハンドル、ソケット、ミューテックスなどのリソースはOSが責任持って解放するよね
どのようなリソースがリークしますか?
135:デフォルトの名無しさん
24/01/11 08:45:02.51 ETJgFBFV0.net
すべてじゃね?
136:デフォルトの名無しさん
24/01/11 08:46:53.81 ETJgFBFV0.net
>>133
すべてじゃね?
それらの選択肢は別に排他的な選択肢じゃないかと
137:デフォルトの名無しさん (ワッチョイ 7f3a-NF1f)
24/01/11 09:02:22.25 dA95iQ6m0.net
OS管理なリソースはアプリの終了なんか知らないってのもあるからなぁ
得にドライバ関連とかな
138:デフォルトの名無しさん
24/01/11 15:30:41.76 hAXa3uBd0.net
>>136
あれ、少なくともAとCは排他的だと思うんだけど
全部の選択肢を選ぶとすると具体的にはどうなるのかな
139:デフォルトの名無しさん
24/01/11 20:09:25.46 AWAYnmwT0.net
今どきのOS使ってたらOSリソースはリークしない
まぁプロセスがゾンビになるのはよくあるが
140:デフォルトの名無しさん
24/01/11 20:09:51.72 AWAYnmwT0.net
>>137
しったかすんな
141:デフォルトの名無しさん
24/01/11 20:12:29.21 h5T3Zf1WM.net
そもそもアプリ的にデータの不整合とか出るから論外だろう
ファイルやなんかの外部データ使わないなら関係ないだろうけど
142:デフォルトの名無しさん
24/01/11 20:12:30.15 AWAYnmwT0.net
よくあるのは異常終了時にファイルをフラッシュしておきたいとかだろ
汎用的にこれを実現するのは結構むずい
143:デフォルトの名無しさん
24/01/11 20:14:10.04 AWAYnmwT0.net
あとコアダンプの観点では例外飛ばさずに即死したほうがいい
144:デフォルトの名無しさん
24/01/11 21:36:53.22 40hQdtQK0.net
エラーだからって一時ファイル山盛り残して放置しないでください
145:デフォルトの名無しさん
24/01/11 22:44:37.94 wlSOhq+Y0.net
質問した者だけど
確かに近代的なOSであればリソースの始末はよしなにやってくれるだろうし、「絶対にデストラクタが呼ばれなきゃ困る」って状況でもなければいちいちすべての例外を捕捉する必要はないのかな(毎回ボイラープレートコードみたいに書くのもやだし)
146:デフォルトの名無しさん
24/01/12 01:18:38.26 P05ikaaEd.net
例外処理って、メモリ破壊やファイルシステム破壊みたいな絶望的な状況を想定しなきゃいけないんだよ。
ファイルに何か書き込んだら他のファイルを壊しちゃうかもしれない、みたいな。
だからファイル関連の操作をしていいのは、ファイルシステム周りの無事を確信できるときだけ。
データを上書き保存とかしていいのは、データとファイルシステム両方の無事を確信できるときだけ。
何も確信できないときは、何もせずに墜ちなきゃいけない。
ってことで例外機構はデフォルトで何もせずに異常終了するようになってるんだよ。
147:はちみつ餃子
24/01/12 02:09:19.72 Z8/dVhwe0.net
理想的には全ての例外はキャッチされるべき。 ただ、現実は理想的ではない。
キャッチするのは対処するためなので想定漏れで思ってもなかったような例外が上がってきた (対処が出来てない) ならそれはバグなんだから検証して修正する必要があるわけだし、検証しやすい形で止まったほうがいい。
C++ ではスタックの巻き戻しの途中で例外を送出したときの挙動は未定義なので通例ではデストラクタから例外を投げないように設計される。
つまりデストラクタでの後始末に失敗したらもうそれを (例外機構の仕組みでは) フォローできない。
想定されてない例外が上がってるときに後始末がちゃんとできずにわけのわからない動作を引き起こしたら検証にも支障がある。
148:デフォルトの名無しさん (ワッチョイ 7f7c-acFs)
24/01/12 09:48:31.22 1nCpSyqU0.net
じゃあ「投げられうるすべての例外に適切な対処ができるのが理想的だが、対処しきれない例外は投げられっぱなしにする(そしてプログラムを即座に異常終了させる)方が、思考停止でとりあえず捕捉しておくよりはまだマシ」ってことになるのかな
みんなありがとう
149:デフォルトの名無しさん (ワントンキン MMdf-7Pe6)
24/01/12 09:51:15.81 Vmsz+UsIM.net
いやいや、ちゃんとデバッグしろよ
こんなやつとは絶対一緒に仕事したくない
150:デフォルトの名無しさん (ワッチョイ 5f4e-1VUN)
24/01/12 09:58:11.40 yLdIK4jH0.net
ライブラリ書くときはライブラリで対処できない例外は握り潰さずに上位で伝搬させろ!と言われてるよね
アプリも同じだと思う
明確に対処すべきことがあるなら例外をキャッチすればいいし
ないならそのままプロセス落としてOSに任せればいいんでない?
151:デフォルトの名無しさん
24/01/12 10:01:16.79 1nCpSyqU0.net
投げられっぱなしにするって言い方が不適切だったかな、別に例外のせいでプログラムが実際に異常終了するのを見ても知らんぷりするって意味じゃないよ
実際にプログラムが異常終了したんだったらその都度原因は突き止めて修正するし、そもそもすべての例外に網羅的に対処するのが現実的なときは最初からそうするよ
152:デフォルトの名無しさん
24/01/12 10:06:03.47 Umd8uX9b0.net
try {} catch {}
153:はちみつ餃子
24/01/12 17:12:14.63 Z8/dVhwe0.net
想定される状況には対処しているならどこで想定漏れがあるかはやってみないとわからない。
経験を蓄積し続けるしかしょうがないんだよな。
蓄積がテストケースの形などになっているとより良いと思う。
154:デフォルトの名無しさん
24/01/12 17:26:50.90 059LeD4FM.net
自分の知らないライブラリの奥底からいつ投げられるかわからない例外なんて対処しようがない
かつスタックアンワインドしたらデバッグの手がかり消えるだけ
155:デフォルトの名無しさん (ブーイモ MM9f-2j6O)
24/01/12 17:44:35.30 bUlwQWI8M.net
setjump()/longjump()
156:デフォルトの名無しさん
24/01/13 13:54:58.62 rNqWj2dY0.net
やっぱC++の例外は悪……
構造化例外ならwindbgでコアダンプを開いて!analyze -vで発生源を調べられる(仕組みは知らん
がC++の例外は例外オブジェクトが持ち出した情報が全て……
という印象……
157:デフォルトの名無しさん
24/01/13 14:10:21.49 rNqWj2dY0.net
やっぱ例外というブツは、
アプリケーション領域においてプログラミがいろんなリソースを取り扱うようになった結果、
C言語流に関数の戻り値で起こり得る全てのエラーを網羅してチェックする方法が
現実的でなくなってきたから設けられたブツなので
>自分の知らないライブラリの奥底からいつ投げられるかわからない例外(>>154
すなわち設計に対して想定外の事象が起きた知らせとしてが飛んでくるというのが基本的かつ本来的な姿
起こりえる全ての例外の処置を書かなければ設計とは言えない主義の人(>>149)は
寧ろ例外の使用をやめてC言語的な書き方で全てのエラーをチェックすべき
(他人様が作ったライブラリが例外を飛ばしてくるのは仕方が無いから全てcatchする
158:デフォルトの名無しさん
24/01/13 14:15:12.02 rNqWj2dY0.net
つなみにOSの内部ではすべてのリソースをOSが管理する前提なので例外の出る幕は無い
OSの設計に対して想定外の事象がOS内部で起きるとかあり得ないじゃない
レトロな(しかしメジャーな)OSがC++ではなくC言語で書かれ続けるのはそういう理由
159:はちみつ餃子
24/01/13 14:21:37.75 3bve4IFf0.net
何が返ってくるかわからん (ドキュメント化されていない) なら返却値の形になっていても正しく対処できないのは同じだろ。
160:デフォルトの名無しさん
24/01/13 14:37:35.65 b/trpwza0.net
例外だとテストしないドキュメントにも書かないというモラルハザードがおきやすいとは言えるだろう
返り値はエラー体系を自分で定義しないといかんからそうはなりにくい
まぁそれでも失敗を安易にfalseに丸めるどアホは多いけど
161:デフォルトの名無しさん
24/01/13 15:22:27.34 o+zGF69d0.net
>>157
>すなわち設計に対して想定外の事象が起きた知らせとしてが飛んでくるというのが基本的かつ本来的な姿
それ一般にはリリース後に起きちゃいけないことでは。プロダクトにもよるが防ぐ努力は必要だと思うがね。
162:デフォルトの名無しさん (ワッチョイ 7291-Qz6p)
24/01/14 13:01:30.73 H7tsxQrq0.net
>>138
全選択肢を同時に選ぶって意味に捉えられちゃったかな?
そうじゃなくて、その選択肢自体が同時に適用すべきレベルのものじゃないと思うの
例外をキャッチするって決めたなら、そこには目的があるよね?
設計手順としては目的を決めてから例外を使おうって判断になるわけ
その目的次第だよね?っていうのがD
目的がリソースリーク防止ならA
Aのような目的を達成するために、目的範囲内でB
デバッグ目的ならC
製品等で客の目に見せたくないなどの営業目的があるならCはダメで、のべつまくなしBというのもあるかもしれない
163:デフォルトの名無しさん (ワッチョイ 7291-Qz6p)
24/01/14 13:06:09.91 H7tsxQrq0.net
大きな目で全工程トータルを考えると全部の選択肢を適用する必要があるし、適用のしどころが違うと思うってのが>>136の真意でした
164:デフォルトの名無しさん (ワッチョイ 7291-Qz6p)
24/01/14 13:12:37.16 H7tsxQrq0.net
>>148
これが正しいかどうかはおいといて、人命に関わらないなら、自分はその考え方に賛成!
完璧にデバッグしろというのは自動車と医療機器など人命にかかわるものだね
重要度に応じて工数のかけ方が変わってくるので、すべてのソフトウエアで一概にこうしなさいとは言えないかな
そういう意味ではD
165:デフォルトの名無しさん (ワッチョイ 4d34-7Ntv)
24/01/14 15:16:56.65 by9QQMRz0.net
>>162
ああ、なるほどね
分かりやすくありがとう、助かりました
166:デフォルトの名無しさん
24/01/15 08:10:14.00 Y8oMeLNI0.net
人命にかかわらない場合であっても、末端の関数が投げる例外の種類を見落としただけでプログラム全体が
いきなり落ちるのは勘弁してほしいし、それを防ぐために全部の関数が投げる例外の種類を全部把握するというのも
無理ゲーに近い。
なので適当なレイヤーごとにざっくり std::exception をキャッチする造りにしてるな。例外の種類で選択したりはしない。
167:デフォルトの名無しさん (ブーイモ MM22-7+/r)
24/01/15 11:54:06.38 0QYW1wwzM.net
キャッチしてその後どうすんの?
168:デフォルトの名無しさん
24/01/15 18:12:26.71 FtZTeDOW0.net
何するか思い付かないならPG辞めろ
貴様には向いてない
169:デフォルトの名無しさん
24/01/15 18:20:04.00 Y8oMeLNI0.net
>>167
そのtryブロックの処理が失敗したものとして処理を続ける。
170:デフォルトの名無しさん (ワッチョイ 46ea-7+/r)
24/01/15 18:42:14.36 Lgn9c/GO0.net
テストケース爆増じゃん
171:デフォルトの名無しさん (ワッチョイ 6ecf-CdjJ)
24/01/15 19:20:39.72 Y8oMeLNI0.net
なんで爆増?
172:デフォルトの名無しさん
24/01/15 20:40:13.04 Lgn9c/GO0.net
その失敗する処理の具体例言ってみて
173:デフォルトの名無しさん
24/01/15 22:10:56.13 Y8oMeLNI0.net
んでテストケース爆増の話は?処理の具体例次第で話が変わったりするとか?
174:デフォルトの名無しさん (ワッチョイ 46ea-7+/r)
24/01/15 22:45:20.95 Lgn9c/GO0.net
依存関係のあるものに影響あるのは当たり前
原因不明の例外起こっても突き進むんだったら擬似的にそのケース作ってテストするわな普通は
出し渋るなら別にださなくていいよ
参考にならなさそうだし
175:デフォルトの名無しさん (ワッチョイ 6ecf-CdjJ)
24/01/15 23:24:57.00 Y8oMeLNI0.net
それはいったい何のテストなんだろう。原因不明の例外を首尾よくキャッチできるかどうかテストしろと言っているんだろうか。
そもそもそういう例外を想定するなら、スルーして影響範囲が広がる方がテストは厄介になると思うがなあ。
176:デフォルトの名無しさん (ワッチョイ 11fb-5Qxc)
24/01/15 23:36:35.23 rchiNbsm0.net
たとえば業務用のラベルプリンターでAPIが提供されてるとか
とりあえず try ~ catch して「印刷中に不明なエラーが発生しました」みたいなまとめかたはあるかなー
177:デフォルトの名無しさん
24/01/23 17:00:13.54 kD0da0AW0.net
すみません。質問させて下さい。次のコードがMinGW-w64 g++ v13.2では --itrでエラーになります。わからないのはVisual studio 2022およびVisual StudioがサポートするClang LLVMでは通って正しく
実行しているように見えます。--itrの仕様がないのはMinGW-w64 g++v13.2が正しいのでしょうか?それともVisual Studioが正しいのでしょうか?
#include <iostream>
#include <unordered_set>
using namespace std;
int main()
{
unordered_set<int> us = { 1,2,3,4,5,6 };
for(auto itr = begin(us); itr != end(us); ++itr) cout << *itr << endl;
auto itr = us.begin();
++itr; ++itr;
cout << *itr << endl;
--itr;
cout << *itr << endl;
cin.get();
return 0;
}
MinGW-w64 g++ v13.2のエラー
// error: no match for 'operator--' (operand type is 'std::__detail::_Node_iterator<int, true, false>')
178:はちみつ餃子
24/01/23 17:23:45.88 MIeJSKFF0.net
>>177
unordered_set は forward iterator をサポートしているという規定がある。
URLリンク(timsong-cpp.github.io)
forward iterator は進めることは出来ても戻ることはできない。
この場合は operator-- がないのが正しい。
拡張してより高機能なライブラリを提供しても仕様に反するってわけではないけど
マイクロソフトのドキュメントでも特に拡張しているという文面は見当たらないから
あんまりあてにしないほうが良さそうには思う。
URLリンク(learn.microsoft.com)
179:デフォルトの名無しさん
24/01/23 17:34:44.31 kD0da0AW0.net
おお、ありがとうございます。
180:デフォルトの名無しさん
24/01/28 11:36:45.25 W0uCnQb30.net
>>173
横やが関数foo()で1つの例外が発生したらその時点のfoo()呼び出しに至る10個かそこらの関数が中断されるわけや
すなわち関数bar()が
処理A→B→C→D→return
の順で処理が進むことを気体しているところに、Bで呼び出している関数baz()がfoo()を呼び出している結果、foo()で例外を生じると
処理A→B→return
という処理順に変更になる。こうなっても大丈夫なようにtry { 処理B } catch ((fooが投げる例外)& e) { (eに対する適切な処置) } を書かねばならず、
これが実は潜在的には処理A、B、C、Dのどこでも起き得るから厳密なことを言えば全てについて書かねばならず、
それがfoo()呼び出しに至る10個かそこらの関数それぞれについて行われねばならない。
検証もそんだけ組み合わせが増える。
181:デフォルトの名無しさん
24/01/28 11:40:58.52 W0uCnQb30.net
というわけでそんなの現実には不可能なので、現実的な処置としては
・ライブラリ製作者はなんか都合が悪い事が起きたら何でも呼び出し元に返す。
第1選択としてはエラーステータスを返すことを検討し、それではコードが煩雑になりすぎる場合は例外を投げて異常を知らせる
・ライブラリを使う人はライブラリが例外を投げない条件で使うことを心掛け、自前のコード内でtry { } catch() { }を極力しない
という処置になるわ
けや
182:デフォルトの名無しさん (ワッチョイ 66cf-5eDQ)
24/01/28 12:02:32.93 Gsm093HM0.net
catchしようがしまいが、例外が起きて 処理A→B→return となるのは同じだと思うが。
その場合の検証が必要だというならどっちも必要だろ。
183:デフォルトの名無しさん (ワッチョイ 6d63-H5uA)
24/01/28 12:13:11.85 W0uCnQb30.net
>>182
>catchしようがしまいが、例外が起きて 処理A→B→return となるのは同じだと思うが。
それは問題の認識がおかいし
例えば以下のコードにおいて、スレッドのゾンビを生じさせないためにはfuncB()をtry { } catch () { } は必須になる。
void bar() {
funcA(); // スレッドxを起動
funcB(); // 中でbaz() → foo()の呼び出し
funcC(); // スレッドxに停止シグナル発酵
funcD(); // スレッドxの終了待ち
return;
}
このように一般に例外が飛んでくる関数にはcatchするかしないかの選択権など無い
例外安全なオブジェクト「だけ」で事が済んでいない限り、例外を受けると決めた時点でcatchせねばならない
一方、例外を生じないライブラリの使い方(関数の呼び出し方)を心掛けるかどうか。これなら選択肢がある
184:デフォルトの名無しさん (ワッチョイ 6d63-H5uA)
24/01/28 12:14:54.75 W0uCnQb30.net
訂正orz
誤:例外安全なオブジェクト「だけ」で事が済んでいない限り、例外を受けると決めた時点でcatchせねばならない
正:例外安全なオブジェクト「だけ」で事が済んでいない限り、例外が飛んでくる想定であるならばcatchせねばならない
185:デフォルトの名無しさん (ワッチョイ 797c-+np5)
24/01/28 12:19:26.10 /bXkl1Cz0.net
>>183
それはfuncB()に失敗の可能性がある時に必ず必要な話だろ?例外どうこうじゃないじゃん
funcB()が例外を投げずに古き良きintのエラーコードを戻り値で返す場合は何かが変わるの?
まさか「funcBの戻り値をガン無視すればfuncCもfuncDも実行されてくれるから完璧!だから例外はクソ!」っていうゴミカスみたいな主張をしたいわけじゃないよね?
186:デフォルトの名無しさん (ワッチョイ 66cf-5eDQ)
24/01/28 12:28:00.13 Gsm093HM0.net
>>183
それはcatchが必要かどうかの話だろ。
catchしたらテストケースが増えるかどうかという話とはなんも関係がない。
187:デフォルトの名無しさん
24/01/28 15:40:48.23 JnoCOYDS0.net
そもそも未知の例外飛んできた時点でそれを通したライブラリの例外安全性が守られてるか怪しいと考えるべき
188:デフォルトの名無しさん
24/01/28 17:01:39.99 Gsm093HM0.net
例外安全性を守るのに例外の種類やそれが既知か未知かは関係ないだろうが、
仕様に明記した例外以外は堰き止めるのが正解だろうなあ。
189:◆QZaw55cn4c (ワッチョイ 3583-LgJ8)
24/01/28 20:27:29.75 0TnCAHFI0.net
思い立って結城さんのデザパタ(古いjava で記述)を総称型(テンプレート)もちゃんと使ってC++ に書き直しているけれども、
new/delete からptr::shared_ptr に書きなおすと、もう構造がわかりにくくなってしまってどうしようもない
デザパタ=抽象クラスプログラミングは C++ ではオワコンなの?
Visitor パターン
new/delete: URLリンク(ideone.com) スッキリ書けてきもちいい
std::shared_ptr: URLリンク(ideone.com) 恐ろしい宣言の連発
>std::shared_ptr<Iterator<std::shared_ptr<Entry>>> iterator() { return std::make_shared<VectorIterator<std::shared_ptr<Entry>>>(v); }
なんかもう書いてても意味不明
CONSTRUCTOR(CONSTRUCTOR *p) とかコピコン以外にもみたことのないコンストラクタが要求されるし
190:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-vdg+)
24/01/28 20:53:25.29 hRRbWEE/0.net
>>189
スマートポインタを使わないバージョンも C++ 的にはすっきりしてない。
動的多態の必要が必要ないのに持つべきメンバ関数を強制するためだけに抽象クラスを使っていて不恰好に見える。
コンセプトの導入がだいぶん後回しになった C++ の問題でもあるんだが……。
設計理念が妥当かどうかはともかくとして、元が Java なら直訳めいた C++ への置き換えがすっきりと書けるはずがない。
191:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-vdg+)
24/01/28 21:08:52.58 hRRbWEE/0.net
ざっと見た感じだと抽象クラスとして必要なのは Entry だけかな。
ジェネリックラムダが visitor パターンで使いやすいのでそういうのが使いやすいように配慮するといいかも。
std::visit が C++ での visitor パターンのお手本だよ。
192:デフォルトの名無しさん (ワッチョイ b501-PlwZ)
24/01/28 22:46:18.85 VLKT1lFt0.net
>>189
usingなりtypedefでエイリアス作れば?
using Entry_Ptr = std::shared_ptr<Entry>;
193:デフォルトの名無しさん (JP 0Hbd-DQL8)
24/01/28 23:17:29.01 wkb3ctO/H.net
面白そうだからちょっと書いてみた。大きな変更点はこんな感じ。
・accept が受け取るのは単に Visitor の参照でいい。ここで shared_ptr を使う必要はない。
・Visitor が受け取るのも File や Directory の参照でいい。
・SizeVisitor もいらない。File と Directory はともに Entry の子クラスとして getSize() を実装してるんだから、無理に visitor パターンを使わなくても単に getSize() を呼べばいいだけ。
・iterator() が返すのも VectorIterator の shared_ptr ではなく、単に VectorIterator を返せばいい。
全体的に使う必要がない場面で shared_ptr を使ってるのが目立ったと思う。
URLリンク(wandbox.org)
だいぶすっきりしたんじゃない?
194:はちみつ餃子
24/01/28 23:52:27.85 hRRbWEE/0.net
なんかもうポインタをいじるのが面倒になったので値としてやりとりしていいやという気持ちと
標準ライブラリを積極的に活用することにしたらこうなった。
URLリンク(wandbox.org)
195:
24/01/29 04:35:04.36 M6sadnnj0.net
>>193
拝読させていただきました。なるほど、関係性を示すポインタ=参照なら std::shared_ptr でくるむ必要ガない、というわけですか。
>>194
拝読させていただきました。Entry を値で持つのはいやだなあ。 dectype の使い方を学ばせていただきました。
196:
24/01/29 05:00:34.95 M6sadnnj0.net
>>194
std::size_t()
あたりから読めていません。operator() をどう使っているのでしょうか?
197:はちみつ餃子
24/01/29 12:08:36.13 WXyC0nMC0.net
スマートポインタを使うにしても std::shared_ptr って必要?
この場合は std::unique_ptr でよくない?
URLリンク(wandbox.org)
設計思想によるけどファイルシステムを表現するという前提だと
ひとつのルートディレクトリに連なる全てのエントリは実質的に一体のデータ構造なので
ルートディレクトリエントリの寿命が尽きれば全て解体ってことにしたほうが簡単でいいと思う。
ハードリンクの表現とかも考えるなら事情が変わってくることもあるだろうけど……。
198:デフォルトの名無しさん
24/01/29 21:21:12.23 eAAuxXw40.net
>>189 c++
URLリンク(ideone.com)
・URLリンク(ideone.com) を元に若干の整理を行った
・他の人と同様shared_ptrを削除
値で持てるところは単に値で持つほうがC++っぽいと思う
ただ「Entry を値で持つのはいやだなあ」とのことなので部分的に残してる
Javaの参照型変数をshared_ptrに置き換えようとして困るのは
size_t File::accept(std::shared_ptr<Visitor> v) { return v->visit(std::make_shared<File>(this)); }
ここがJavaだと単にvisit(this)で済むからスッキリするんだけど
しかもこれmake_shared(this)だと多重開放するよね??
>>189 c++
URLリンク(ideone.com)
・URLリンク(ideone.com) を元に若干の整理を行った
・make_shared<File>(this)の多重開放?を修正
std::enable_shared_from_thisを使ってJavaの参照型変数っぽい使用感を得た。
・struct this_is_private {};
これは単にコンストラクタを実質的にprivateにするためだけに使ってる
URLリンク(en.cppreference.com)
URLリンク(stackoverflow.com)
このへん参照されたし
199:デフォルトの名無しさん (JP 0Hbd-IHfd)
24/02/03 04:38:02.47 bq1KvR69H.net
URLリンク(wandbox.org)
なんか「子クラスのコンストラクタに親クラスのオブジェクトを渡して子クラスのメンバを初期化する」(?)みたいなことができちゃってるんだけど、これってどういう仕様でこうなってんの?
Wandbox上だとC++2aではコンパイルできてC++17ではコンパイルできなかったからcpprefjpのC++20の機能の一覧も見てみたけどそれらしいものはなかったし
200:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-MxBP)
24/02/03 09:26:19.03 Sz70frqK0.net
>>199
designated initializer も C++20 からの機能なんだけど……それは脇に置く。
この場合は集成体初期化に該当する。
C++17 から基底の初期化も集成体初期化で扱えるので
child c{p};
というように初期化出来ていた。
更に C++20 では集成体初期化を丸括弧で書いても良いことになったので
child c(p);
とすることが許されるようになった。
201:◆QZaw55cn4c (ワッチョイ 3555-LgJ8)
24/02/03 09:46:38.23 21sfApha0.net
>>198
>size_t File::accept(std::shared_ptr<Visitor> v) { return v->visit(std::make_shared<File>(this)); }
> ここがJavaだと単にvisit(this)で済むからスッキリするんだけど
> しかもこれmake_shared(this)だと多重開放するよね??
多重解放(二重解放)しないことはラッパをかませて確認済みです。そう簡単に std::shared_ptr は破綻しないと信じています
URLリンク(ideone.com)
それはともかく、皆様のご意見には感謝しております。これからもお伺いさせていただいた際にはよろしくお願いいたします。
202:デフォルトの名無しさん (JP 0Hbd-IHfd)
24/02/03 09:48:07.39 bq1KvR69H.net
>>200
URLリンク(cpprefjp.github.io)
これかあ
実は「childにコンストラクタがある場合」とか「childにprivateメンバがある場合」とか「childがparentをprivate継承している場合」とかはコンパイルが通らなくてもう意味が解らなかったんだけど、それもchildが集成体じゃなくなってたからだったんだね
ありがとう、勉強になった
203:◆QZaw55cn4c (ワッチョイ 3555-LgJ8)
24/02/03 10:15:36.86 21sfApha0.net
>>198
>値で持てるところは単に値で持つほうがC++っぽいと思う
時代の流れを感じさせるお言葉です。なにせ K&R1 で育った世代なので(K&R1 では構造体の実体渡しはできず、かならずポインタで渡さなければならなかった)。
C++ においても、コピコンを働かせないために const & を多用する毎日です
204:はちみつ餃子
24/02/03 14:49:57.28 Sz70frqK0.net
>>203
内部的に値で持つのでもポインタで持つのでもいいけど
「簡単に値として取り出せる」のはあまりよろしくないと思う。
これ (>>189) がおそらくファイルシステムを表現しようとするもの
だという前提を考えたらオブジェクトの構造も
ファイルシステムのモデルを抽象するものであるべきだと思うから。
ファイルはそれがある場所にも意味があるからファイルを象徴するオブジェクトが
場所から離れてやりとりされるのは違和感がある。
まあファイルシステムのモデルをどう捉えるかは私の感想でしかないから
何が妥当とは強くは主張しないけど、
いずれにしても実装上の都合じゃなくて使う側の感覚でどうなってて欲しいかという視点が要ると思う。
205:デフォルトの名無しさん (ワッチョイ f7da-tydm)
24/02/04 11:53:17.97 nmDLw2WS0.net
はちみつさん頭いいね
アドバイスが丁寧かつ的確でいつも感心する
206:デフォルトの名無しさん (ワッチョイ 5702-VoFb)
24/02/05 20:47:16.57 dvRwXcQL0.net
ある構造体(集成体)Aについてconstexprでa1, a2, a3・・・といくつか作りました
別のクラスBのメンバ変数にconst A* m_ptrAがあってconstexprで作ったインスタンスのどれかを指すことにします
この時Bのメンバ関数などで、
if(m_ptrA== &a1) という比較・条件分岐を行うのは意味のある比較になっているのでしょうか?
207:デフォルトの名無しさん (ワッチョイ bfe1-tai3)
24/02/05 21:20:14.92 crhbGtf+0.net
意味はある
でもなるべくそういう判定は無しでいけるように設計したいところだよな
Aクラスを作ってる意義が薄れる
あと細かいこと言えばaddressofを使ったほうが汎用的というのはある
c++のクソっぷりが如実に表れている関数
208:デフォルトの名無しさん (ワッチョイ 5702-VoFb)
24/02/06 11:08:08.32 KJUqS3Ww0.net
ありがとうございました
本当に列挙型代わりに使えるのなら面白いとも思いましたが
まあ変なコードには間違いないですね
209:はちみつ餃子
24/02/06 12:11:55.01 gR/xoQQt0.net
分岐の内容次第ではあるけど……Bが指しているAのオブジェクトごとに処理を切り替えるってのなら
a1, a2, a3 …… がそれぞれ関数 (関数オブジェクト) を指す (所有する) ようにするのが常道ではあるね。
Bのメンバ関数の中では呼び出しを一文書くだけでいい。
分岐条件を網羅しそこなうしょうもないミスはよくあることだから
手作業での網羅を避けられるならそのほうがいい。
210:デフォルトの名無しさん
24/02/06 20:42:09.19 WnlTLfV5M.net
「The C Standard says that array indexes are (signed)
integers.
The reason behind that is that pointers and arrays
are close in C. For example, tab[index] is strictly
equivalent to *(tab + index). You can use pointer
arithmetic with negative values, hence an array
index can be negative」
とあるので、C 言語での配列添え字は符号付き整数
ですね。
しかし、C++ では、size_t とされ、符合なし整数
のようですが、矛盾しませんか?
VC++の以下のマクロでは、
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
eが偽の時にエラーになるようになっているようです。
これはつまり、
typedef char aaa[-1];
がエラーになる事を前提にしているようです。
しかし、もし、配列の最大要素数が、符合なし整数
であるならば、32BIT 環境の場合、
-1 は、0xffff_ffff と同じと言えば同じであるはずで、
コンパイラ内部で効率よく区別するのは難しいはずです。
どうしてるんでしょう。
211:デフォルトの名無しさん
24/02/06 20:47:53.26 WnlTLfV5M.net
何がいいたいかと言えば、32BIT環境だと
符号付き整数の最大値は、
0x7fff_ffff ですから、
char a[0x7fff_ffff];
は合法ですが、
char a[0xffff_ffff];
はエラーです。よって、
char a[-1];
はコンパイラは難しい処理をしなくても、
-1 は内部表現が 0xffff_ffff ですので
そもそも範囲外の数値と見なせます。
ところが、もし、配列最大数が unsigned
の領域まで許されるならば、要素数が
0xffff_ffff の配列も合法だということに
なります。
ならば、要素数の[] の中に-1 を指定した
場合の処理は難しくなりそうだ、ということです。
なおそもそも、32BIT の Windows 環境
だと、ユーザーが使えるアドレス空間は
最大で 0x7fff_ffff 程度までですから、
バイト数的に確保は出来ませんが。
ならば、そもそも、C++がunsigned 型
であるところの、size_t を採用しているもの
なかなか不可思議であります。
212:デフォルトの名無しさん
24/02/06 21:10:01.10 cxCkHHUF0.net
長いからよく読んでないけどコンパイラは型を認識をしてんだから-1と0xFFFFFFFFは区別してるだろ
213:デフォルトの名無しさん
24/02/06 21:25:24.39 82wR+tAN0.net
call -151
214:デフォルトの名無しさん
24/02/06 22:29:48.57 SZ6XHr3I0.net
C++の配列添字はstd::ptrdiff_t(符号付き)です
215:デフォルトの名無しさん
24/02/06 22:36:10.13 pbGHBGq1H.net
配列を宣言するときの構文と添字演算子を使うときの構文を混同してない?前者はブラケットの中身が正じゃなきゃだめで後者は負でもいいってだけの話だと思うんだけど
int main()
{
int hoge[-1]; // ここで負の値を指定することはできない
hoge[-1]; // でもこれはいい (*((hoge)+(-1)) と解釈される)
}
せっかくだからC++23の仕様書も見てみたけど、§9.3.4.5の1には「配列のサイズはstd::size_t型(に変換された)定数式で、その値は0より大きくなければならない」って書いてあって、§7.6.1.2の2には添字は「スコープ無し列挙型か整数型」て書いてあったよ(該当箇所だけつまみ読みしたから正しく読めてる保証はできないけど)
216:はちみつ餃子
24/02/07 01:09:12.04 kuiQPbhX0.net
>>210
C の配列宣言子の角括弧内に書ける数値は 0 より大きい値に評価される整数定数式であることが条件で、具体的な型に規定はない。
式の型がなんらかの具体的な型に強制 (型変換) されたりはしないので signed int なら signed int だし、 unsigned int なら unsigned int のままだ。
VLA のときは定数式という条件は外れるけどそれ以外の制限はだいたい同じ。
C の添字演算子の場合もそう。 型は整数であればよい。
(値は制限の範囲内である必要はある。)
どこで見た説明を根拠にしているのか知らんけど、その signed が括弧書きなのは signed 「でもよい」という意味だと思うよ。
217:デフォルトの名無しさん
24/02/07 12:42:17.44 7NJYw5ei0.net
std::functionって、有効な関数がセットがされているかどうかでブール値を返しますが、
一旦有効化した後にこれを無効化したい場合って、nullptrを代入したりしていいんでしょうか
そしてその場合std::functionの中身はうまいこと解放されたりするんでしょうか
場合によってはラムダ式を使ってオブジェクトをキャプチャしていたりして
あまりその辺りの説明が見当たらない感じがしました
218:デフォルトの名無しさん
24/02/07 12:56:29.41 0txhPX/d0.net
それでいいよ
219:はちみつ餃子
24/02/07 13:12:18.32 kuiQPbhX0.net
>>217
URLリンク(timsong-cpp.github.io)
220:デフォルトの名無しさん (ワッチョイ bf9a-Ehcu)
24/02/07 14:19:19.97 7NJYw5ei0.net
>>218
ありがとうございます!
221:デフォルトの名無しさん
24/02/07 18:20:13.87 aGYGzZDDM.net
>>212
>長いからよく読んでないけどコンパイラは型
>を認識をしてんだから-1と0xFFFFFFFFは
>区別してるだろ
char a[100-101];
みたいに結果的に -1 になった場合は、
32BITコンパイラの場合、果たして内部で
0xffff_ffff
と区別をつけているかどうか。
unsigned型と考えれば0xffff_ffffであり、
signed型と考えれば -1 です。
ターゲットが 32BIT Windows どちらもエラー
になる可能性は高いですが、理由は結構異なる
と言えば異なると思います。
222:デフォルトの名無しさん
24/02/07 18:25:16.10 aGYGzZDDM.net
もっと言えば、32BIT ターゲットで、
char a[0x80000000 | 1];
みたいな場合、中味は signed と
捉えれば「負数」ですが、unisgned と
捉えれば、0x80000001 という大きな値
に過ぎません。
どちらもエラーになる可能性が高いですが。
223:デフォルトの名無しさん
24/02/07 18:40:38.44 0txhPX/d0.net
リテラルにも型がある
1はint
0x80000000はunsigned int
演算結果はunsigned int
ルール決まってるから
224:デフォルトの名無しさん
24/02/07 18:55:38.23 V2I2BIn30.net
x86のアセンブラのディスプレースメントは符号付いてるけどな
他のマシン系はワカランけど
225:デフォルトの名無しさん (ワッチョイ bfa4-syIJ)
24/02/07 20:52:20.31 L6yrYnPT0.net
>>222
32bit環境には64bit整数はないと思ってるの??
226:デフォルトの名無しさん (オイコラミネオ MMeb-tjaG)
24/02/08 18:55:38.81 DVUqgRU9M.net
>>223
なるほど。そうなるわけですね。
本当に書いた人の意図がどうかに関わらず、
規則で決まっていると。
1UL のように書いてあれば unsigned。
そして、UL のようなものを書いてない場合、
1 のように小さな値は、signed ですが、signed の
範囲を越えるようなものは、unsigned になる、
などの規則があるわけですね。
227:デフォルトの名無しさん (オイコラミネオ MMeb-tjaG)
24/02/08 18:56:00.93 DVUqgRU9M.net
>>225
そういう問題ではないようですが。
228:デフォルトの名無しさん (ワッチョイ 5763-dZsi)
24/02/10 12:18:06.78 KJGevrBa0.net
>>185
>>183の主張の
>一方、例外を生じないライブラリの使い方(関数の呼び出し方)を心掛けるかどうか。これなら選択肢がある
が完全に読み飛ばされている件について:
例外を生じないライブラリの使い方で設計したら、funcB()から例外が飛んでくるのはバグなので
調査と修正の対象になる。
(結果的にやっぱtry { funcB(); } catch (/*略*/) { ... } いるじゃーん?となる可能性はあるがたいていはそうはならない
>>188のように自分が何をやっているのか認識しないまませき止めるのは論外すぐる……
229:デフォルトの名無しさん (ワッチョイ 5763-dZsi)
24/02/10 12:26:53.58 KJGevrBa0.net
>>186
>catchしたらテストケースが増えるかどうかという話とはなんも関係がない。
あっる
catchする必要性箇所を設計で厳選すればcatchが減るのだからテストケースは減らし得る
例外を使う場合:
スルーしたりcatchして再スローが生じるfoo()の呼び出し箇所(とするのが現実的でないなら呼び出しパティーン)がm個、
スルーしたりcatchして再スローする段数が(簡単のためここでは平均とする)a個、
foo()が例外を生じるパティーンがn個なら、m^a^n個のテストケースが必要なところであるが
catchする必要性箇所を設計で厳選した場合:
foo()の呼び出し箇所(とするのが現実的でないなら呼び出しパティーン)がm個だとしたら、
例外が飛んでこないことを確認するのテストケースがm個のオーダーで要るだけ……
230:デフォルトの名無しさん
24/02/10 16:57:16.73 Qku1mp0Z0.net
>>228
読み飛ばしてねえよ
funcB()は処理を中断すべきエラーが発生する可能性があるんだろ?だったらそれを適切に処理して後続の処理をやったりやらなかったりする必要があるわけだろ?
それはfuncB()がエラーを例外で返そうと戻り値で返そうとなんか他の方法で返そうと何も変わらないはずじゃないか
231:デフォルトの名無しさん
24/02/10 18:55:23.41 0f3gz8pL0.net
>>229
>例外が飛んでこないことを確認するのテストケースがm個のオーダーで要るだけ……
いったい何をテストしようとしているんだろうか。
仮に「例外が飛んでこないことを確認するテスト」なるものができたとして、catchしたらそれができなくなるのか?
前半のよくわからない計算はcatch句を書いたらそのC0網羅のためのテストケースが必要になるとかいうことなんだろうか。
232:デフォルトの名無しさん
24/02/10 20:56:08.28 0f3gz8pL0.net
>>228
>>>188のように自分が何をやっているのか認識しないまませき止めるのは論外すぐる……
どこが論外?>>169でぜんぜん問題ないが。
233:デフォルトの名無しさん (ブーイモ MM8f-tai3)
24/02/10 21:22:31.20 dL54PN9cM.net
>>232
それは未知の例外投げてきたライブラリを信用し過ぎ
製品ならそういう「たぶん大丈夫っしょw」的なのは許されないね
234:デフォルトの名無しさん
24/02/10 22:40:34.32 0f3gz8pL0.net
>>233
逆だろ。catchしないのはライブらにが未知の例外を投げてこないだろうと信用してるってことだろ。
235:デフォルトの名無しさん (ワッチョイ bf27-tai3)
24/02/10 23:44:13.35 iRyhZExm0.net
>>234
catchしないということは終了させるということ
見かけ上動き続けたらいいってもんじゃない
236:デフォルトの名無しさん
24/02/11 03:08:09.08 4PD3HqyC0.net
>>232
それは未知の例外投げてきた原因を調査しなさすぎ
製品ならそういう「たぶん大丈夫っしょw」的なのは許されないね
>>233
ドキュメント通りに例外発生条件にならないように呼んでやったのに
例外を飛ばしてくるライブラリって一体……
製品やぞ……
237:デフォルトの名無しさん
24/02/11 03:16:41.24 4PD3HqyC0.net
質問なのですが
Q1. std::ldexp(0.0, 0.0) が0.0なのですがこれは 0^0 = 0という大胆な主張なのですが何で決まっているの?
STLがIEEE735に従っているだけ?
Q2. 最小の(絶対値が最小の正の)非正規化数は
const auto min_expn = std::numeric_limits<double>::min_exponent;
const auto digits = std::numeric_limits<double>::digits;
として、std::ldexp(0.5, min_expn - digits + 1) で正しい?
(実際 std::ldexp(0.5, min_expn - digits + 1) > 0.0 やが std::ldexp(0.5, min_expn - digits + 1) / 2.0 == 0.0 であっる
Q3.にもかかわらず、
std::ldexp(0.5, min_expn - digits) > 0.0 になるのはなんで……orz
238:デフォルトの名無しさん
24/02/11 03:25:12.56 4PD3HqyC0.net
訂正 |||。n_
誤1: IEEE735
正1: IEEE754
誤2: 非正規化数
正2: 非正規数
239:デフォルトの名無しさん
24/02/11 06:22:40.58 2tL2xZqD0.net
>>237
wandboxに書いてみ
240:はちみつ餃子
24/02/11 07:55:26.62 nHqSm2on0.net
>>237
決まっていない。言語仕様としては未規定。
std::numeric_limits::is_iec559 が真であるならその挙動をあてにしていいがそうでないときは各環境の事情による。
241:デフォルトの名無しさん (ワッチョイ 16cf-BOeC)
24/02/11 09:19:29.20 XOPhWcHA0.net
>>236
あんたの認識じゃ catchする=見かけ上動き続ける なんだ?
なんか根本的に勘違いしてる気がする。
242:デフォルトの名無しさん (ワッチョイ 637c-IqbK)
24/02/11 09:29:04.38 9XvrSVak0.net
例外は「関数外にエラー発生を伝える」ための「方法の一つ」でしかない
関数の処理がどんなエラーを発生させうるか、受け取った外側の処理がその情報をどう取り扱うべきかという問題とは完全に直交してる
(言語ごとにある程度の慣例はあるけどあくまで慣例)
例外に変なこだわりや的外れな批判をしてる奴は大体そこを勘違いしてる
243:デフォルトの名無しさん (ワッチョイ 16cf-BOeC)
24/02/11 09:47:48.61 XOPhWcHA0.net
アンカ間違えた、すまん
>>241は>>235宛な。
244:デフォルトの名無しさん (ワッチョイ 1e27-2ki6)
24/02/11 09:47:48.79 2tL2xZqD0.net
>>242
お前はバグのないお花畑を考えてるからそういう理想的な抽象論を持ち出すんだよ
c++の現実は道を踏み外したら即カオス
stlのコンテナのpopに返り値がない理由は知ってるか?
あのレベルの考察でソフトウェア設計している人間が世の中にどれだけいると思う?
245:デフォルトの名無しさん (ワッチョイ 1e27-2ki6)
24/02/11 09:55:44.37 2tL2xZqD0.net
>>241
>>169を否定している
知らない例外が飛んできた場合にcatchして握りつぶしてそのまま動作を継続するかどうかって話な
246:デフォルトの名無しさん (ワッチョイ 637c-IqbK)
24/02/11 10:07:06.72 9XvrSVak0.net
>>244
バグのあるなしなんか関係ない設計の話だし、「例外はエラー伝達の具体的方法の一つ」って話のどこが抽象的なのかも分からないし、
「C++の現実」とか「カオス」が具体的に何のことで何の関係があるかも分からないし
STLにpopがないのはnoexcept moveがない時代に例外安全に出来なかったからだけど今の話に何の関係があるかわからないし
そんなのまともなC++erなら誰だって考えて設計してると思うけど、そうでないタコの話が何の関係あるかわからないし何もかも分からなすぎてすごい
仕事でそんなドキュメントやレビューコメント出すなよ
>>245
知らない例外を握り潰すのも、知らない戻り値をガン無視するのも一緒
errnoが変わってるのを無視するのもint*err引数に渡した変数の値を無視するのもexpected<T,E>で帰ってきたEを無視するのも「知らんエラーを無視した」という結果は一緒
知らんエラーを無視していいかどうかの意味論と、そのエラーがどう伝播して来るかかは関係ない
関係ない話を混ぜるからお前のC++はカオスなんだよ
247:デフォルトの名無しさん (ワッチョイ 16cf-BOeC)
24/02/11 10:14:56.00 XOPhWcHA0.net
>>245
?
そのtryブロックの処理が失敗したものとするって書いてあるじゃん。
248:デフォルトの名無しさん
24/02/11 11:18:37.96 4PD3HqyC0.net
>>231
>前半のよくわからない計算はcatch句を書いたらそのC0網羅のためのテストケースが必要になるとかいうことなんだろうか
例外が関数の階層をぶち抜いてfall-throughしてくることを忘れている発言
1. catchが書かれた関数が正しくcatchし、適切に処理するか(処理してせき止め or/and 必要な場合再スロー)(←要テスト!
2. fall-throughする関数が例外による処理の中断でおかしいことにならないか(←要テスト!
2をテストもせずに放置するとおかしくなる例は>>183のとうーり
これにより、例外を生じる関数foo()の呼び出しパティーンn個それぞれに対し、a個のテストが必要になっる
例外を発生させない使い方をするなら、n*a*mではなくmの定数倍(例外を飛ばさない使い方に依存擦る定数)。
例外が飛んで来たらバグ。わかりやすい
例外を多用しつつn*a*mをよくわからない計算とか言っている時点で以下略
249:デフォルトの名無しさん
24/02/11 11:18:50.45 4PD3HqyC0.net
>>244
以下の主張のどこが抽象論なのかkwsk、
1. ライブラリのドキュメントに従い、可能な限り例外を生じない使い方で設計する(>>236
2. 例外が生じない前提としたところは例外が生じないことをテストする(m個のオーダー)(>>229
3. 1と2の過程で意図に反して飛んでくる例外がある場合は原因を調査し、修正を試みる(>>228 例外が飛んで来たらバグ
4. 3を意図通りの形で解決できないことが判明した場合は
(ライブラリの使用方法の当方の誤解、ライブラリのドキュメントの不備、ライブラリの作りの粗さによりこれはあり得る、
結果的にtry { } catch (/*省略*/) { ... }を付ける可能性もある(>>228
5. 例外を複数段fall-throughか再スローを許し、かつそれが起きた後もプログラムの
正常な動作の継続を意図する場合はテストケースが爆発する(>>
設計し、検証し、必要とあらばtry { } catch ( ) の追加も含めた修正を行うと言っているのやぞ;;;
いっぽう藻前らの主張は
1. 例外をせき止めれば良い(←処理不能な未知の例外が飛んでくることが無いというライブラリに対する全幅の信頼
2. 例外を処理したりfall-throughしたり再スローしたりする関数はn*a*m個のテストしなくても動くっしょ
(←自己のコードに対する無制限の気体
3. ドキュメントは100%信頼せず、読まない
の3成分からなるわけやが……
250:デフォルトの名無しさん
24/02/11 12:01:58.52 XOPhWcHA0.net
>>248
>例外が関数の階層をぶち抜いてfall-throughしてくることを忘れている発言
やっぱり意味不明だな。catchすれば「階層をぶち抜いて」ってことはないわけだが。
>2. fall-throughする関数が例外による処理の中断でおかしいことにならないか(←要テスト!
もしそのテストが必要なんだとすれば、catchしない場合はその例外が通過する
呼び出し階層全部でテストをしなきゃならないってことになるが。
251:デフォルトの名無しさん
24/02/11 12:31:22.40 XOPhWcHA0.net
>>249
>1. 例外をせき止めれば良い(←処理不能な未知の例外が飛んでくることが無いというライブラリに対する全幅の信頼
なるほどな。
catchする⇒無視する、握りつぶす って脳内変換されてんだな。
catch書いたからといって上に挙げられたようなテストができなくなるわけじゃないっしょ。必要と思うならやればいい。
3.の意図しない例外の原因調査なんて main() に例外が上がってきてプログラムが落ちてからより
発生個所に近い下層で catch できた方がはるかに調査しやすいと思うんだがな。感覚が違うなあ。
252:デフォルトの名無しさん (スプッッ Sd52-oDfP)
24/02/11 12:37:47.91 AyRTgUB7d.net
仕様書や規格書はその意図を正確に読み取ろうとするのに
掲示板の他人の書き込みは積極的に曲解しようとするのは何故か?
253:デフォルトの名無しさん (ワッチョイ ef8b-u/MX)
24/02/11 12:44:06.42 E8bU9+6D0.net
見下しているからよ
こいつらは俺より下なはずと
254:デフォルトの名無しさん (ワッチョイ 5eda-5kwM)
24/02/12 07:49:39.70 4SfsXRB60.net
本気で面白いと思ってやってんだろう
255:デフォルトの名無しさん (ワッチョイ 637c-IqbK)
24/02/12 08:44:56.68 WngRm50l0.net
例外は糞!危険!意味不明!テスト漏れる!って言ってる奴ほど
if (err != 0) { return -1; }が大好きなんだよな
本質的にやってること変わらないのに
256:デフォルトの名無しさん
24/02/12 15:42:15.86 NdUIQhSh0.net
ファイル名に年月が使えないの困ります。
2024/02/11_データ.txt
とか
257:デフォルトの名無しさん
24/02/12 15:46:00.47 QicyHe7E0.net
>>256
それ検索性最悪だから良くないんだよなぁ。
データ/2024/02/11/データ.txt
データ.txt/2024/02/11/データ.txt
あたりならまだ許せる。
258:デフォルトの名無しさん
24/02/12 16:40:43.94 MdmHk5EH0.net
ふつう年月日はハイフンで区切るよね
259:はちみつ餃子
24/02/12 17:02:03.84 4VueJhli0.net
スラッシュを使う習慣が悪いわけではないが
プログラマの感覚だと ISO 8601 の方式に馴染みが有ることが多いってのはある。
260:デフォルトの名無しさん (ワッチョイ 5edc-s3Gl)
24/02/12 17:31:20.60 rGOG+Ewu0.net
年月日は「ふつう」がないのでみんなが苦労している
日本とアメリカとイギリスで順番が違うし
日本には「令和」とかあるし
261:デフォルトの名無しさん
24/02/12 18:43:50.33 zGvIVge80.net
Windowsでも / をディレクトリ区切り文字として使えるけど(場面は限定的かもしれないけど)、その認識で使ってるのかな…
262:はちみつ餃子
24/02/12 20:07:00.91 4VueJhli0.net
Linux で * という名前のファイルを消そうとして
うわあぁぁぁとなった話はたまに聞く。
使えたとしても使うべきでない文字もある。
263:デフォルトの名無しさん (ワッチョイ f7cb-nOVH)
24/02/12 21:44:07.99 zGvIVge80.net
262>>
それ以外のファイルをすべて退避した上でディレクトリごと削除したことがあったな
264:デフォルトの名無しさん (ワッチョイ f7cb-nOVH)
24/02/12 21:46:10.68 zGvIVge80.net
すみません、261ですが、Windows限定の話ではなかったですね
失礼しました…
265:デフォルトの名無しさん (ワッチョイ 5edc-s3Gl)
24/02/13 05:53:49.07 QIUviIGO0.net
Linuxならi-nodeをしていすれば
findと組み合わせてどんな名前のファイルも消去できるんだけどなあ
windowsはなんか複雑だったような気がした
266:デフォルトの名無しさん
24/02/13 09:36:03.89 7CLA20rP0.net
iso8901にしない人はたぶんこの規格を知らないわけで意識低すぎだろと思ってしまう
267:はちみつ餃子
24/02/13 11:18:57.32 T85IlqBy0.net
>>266
ISO 8901 は情報交換用 (要するに機械同士のやり取り) の時刻フォーマットを定める規格であって
言葉や文章で使うもの (人間が読み書きする目的) ではないと適用範囲の言及がある。
ファイル名はどちらの用途もありうるので >>256 がどのような状況を想定しているかによって
ISO 8901 が適切かどうかは違う。
もし非技術者向けのシステムなら
文化固有の日付表現に対応できてないほうが意識低いという見方もある。
268:デフォルトの名無しさん
24/02/13 12:55:27.90 c63MYIIQ0.net
>>267
エンドユーザーの文化的背景に配慮したデータフォーマットの利点は、エンドユーザーの知識やメタファーを利用した学習曲線の低勾配化であって、技術的には負の遺産になりやすいことには注意が必要。
典型的には小組織から始まるURLの並びですな。木構造との相性がひどく悪い。
あるいは大きな桁から始まるバイト列とか。あんなの1桁目から始めればエンディアン問題とか無かった。
269:デフォルトの名無しさん
24/02/13 13:07:38.28 mTl8FNrx0.net
> 典型的には小組織から始まるURLの並びですな。木構造との相性がひどく悪い。
それは人間から見たときと機械から見たときの見やすさの違いでしかないような気がする
でも日本の住所は大きい方から始まるんだよな
アメリカは個人から始まる
文化の違いやけども、日本人は機械生命体だったのかもしれぬ
270:デフォルトの名無しさん (ワッチョイ 6b74-e92p)
24/02/15 04:22:25.92 MOgQCM5N0.net
>>58
亀だがクロスで使ってるよ
271:デフォルトの名無しさん
24/02/16 22:41:08.10 /bcZ41DF0.net
enable_shared_from_thisなクラスで、shared_from_this()はコンストラクタの中では
呼べないようですね
コンストラクタの中の処理でthisを渡したい処理があるのですが、どうしたら...
そもそもそれ自体が間違っているのでしょうか
コンストラクタが呼ばれる行の次でその処理を呼べばいいという説もありますが、
現在のコードがそれをやりにくい形になっていて
272:デフォルトの名無しさん
24/02/17 11:55:24.05 hsYxYbKj0.net
>>250
>>2. fall-throughする関数が例外による処理の中断でおかしいことにならないか(←要テスト!
>もしそのテストが必要なんだとすれば、catchしない場合はその例外が通過する
>呼び出し階層全部でテストをしなきゃならないってことになるが。
その通り。テスト不要としたいなら、例外が出た原因を調べて出ないようにするのが筋
原因を調査して対策せずに予防的にテスト不十分のtry { } catch () をてんこ盛りにする方がソフトウェアー品質が上がるという考えのはおかしい
>>251
>catchする⇒無視する、握りつぶす って脳内変換
脳内変換ではなくて、予防的に入れたtry { } catch ()部分のテストが不十分な限り事実じゃーん?
>>252
>本質的にやってること変わらないのに
別に。
return -1; は呼び出し側のバグで見落とすかもしれないが
throw std::logic_error("*** ERR ***"); なら悪評千里を走ってバグの兆候が嫌でもワカル
むしろ予防的なtry { } catch () が例外のメリットをreturn -1; に縮小してゐる