1 名前:デフォルトの名無しさん (ワッチョイ efda-9b8G) mailto:sage [2023/10/31(火) 07:37:38.52 ID:+ZyYyqMO0.net] !extend:checked:vvvvv:1000:512 !extend:checked:vvvvv:1000:512 ↑同じ内容を3行貼り付けること 次スレは>>980 が立てること 無理なら細かく安価指定 ※前スレ C++相談室 part164 https://mevius.5ch.net/test/read.cgi/tech/1683600652/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
32 名前:デフォルトの名無しさん (ワッチョイ 454e-0SSA) [2023/11/05(日) 14:18:09.07 ID:Qkn7cpbH0.net] 言っている意味がよく分からないが、純粋なポインタにはムーブという概念はないよ ムーブを定義できるのはクラスに対してだけ 他の人も言っているようにムーブといっても実体は単なる関数呼び出しなので、その中でプログラマが自分の責任で必要なコードを書くことになる
33 名前:デフォルトの名無しさん (ワッチョイ 653d-2MVi) mailto:sage [2023/11/05(日) 14:58:05.35 ID:vIwIC4VV0.net] 質問した人じゃないけど説明ありがたいです ムーブ難しいと思ってたけどもっと早く勉強して仕事で使うべきだった (文法解析した要素をポインタいじって並べ変えるんだけど… 二重所有を防ぐのを手作業コーディングで責任を持たなければならないプログラムを作ってしまった)
34 名前:デフォルトの名無しさん (ワッチョイ 454e-0SSA) [2023/11/05(日) 15:15:28.75 ID:Qkn7cpbH0.net] ただ、右辺値参照を使うと、通常の参照や代入と使い分けるためにconstやnoexceptを厳密に指定しないといけなくなりがちだから、 その辺の総合的な理解が必要になってくるのは注意点だね constは一度付け始めるとライブラリ全部に伝染するからな・・・それを嫌って使わない派も結構いる(いた)よね
35 名前:デフォルトの名無しさん (ワッチョイ ed7c-9LC0) mailto:sage [2023/11/05(日) 15:39:17.77 ID:Vx5ySS520.net] 実際のコードだとポインタのムーブはunique_ptrとかにぶん投げで、自分で移動コード書くことはまずないな 自分でムーブ特殊関数の中身書くのはハンドル的なもののムーブを実現したいときくらい
36 名前:デフォルトの名無しさん mailto:sage [2023/11/05(日) 16:12:35.07 ID:jiV3XvQ2a.net] とにかく unique_ptr が便利すぎるから何でもかんでも全部 unique_ptr 使うようになってしまった まあそれでいいのかもしれないが
37 名前:デフォルトの名無しさん [2023/11/05(日) 16:21:29.02 ID:ol9bMVcca.net] >>33 銀の弾丸ではない 手作業コーディングで責任を持たなければならないのは変わらない
38 名前:はちみつ餃子 mailto:sage [2023/11/05(日) 17:10:59.04 ID:pHGS9osC0.net] 所有権管理も結局はプログラマが書く (間違いを部分的にコンパイルエラーとして検出できることはある)、 所有権って具体的に何なんだってのはクラス定義に押し込めるという風に管理のレイヤを分けることが出来るってわけ。 クラス定義をした後は具体的に何をやってるのかを忘れて 所有権というものだと思い込むことが出来るという抽象化の仕組み。
39 名前:デフォルトの名無しさん mailto:sage [2023/11/07(火) 10:10:32.04 ID:5c9945xO0.net] >>37 アホか 普通に考えて、そのコード(クラス)の利用者が所有権について明示的に何かしなきゃいけなかったということだろ
40 名前:デフォルトの名無しさん mailto:sage [2023/11/07(火) 19:02:58.77 ID:Z7KocuHY0.net] >>33 エスパーするけど多分その用途だとmoveは使えない。 データを共有している感じなので素直にshared ptrを使うのがいいかと。shared ptrで性能的にキツイならshared ptrを参照渡しするか。
41 名前:デフォルトの名無しさん mailto:sage [2023/11/07(火) 19:09:56.10 ID:Z7KocuHY0.net] >>40 ちょっと補足すると、戻り値をshared ptrの参照にするのはNGですな。そこは素直にRVOに期待するのが良いか。
42 名前:デフォルトの名無しさん mailto:sage [2023/11/09(木) 17:23:48.54 ID:Op1F6lz40.net] VC++なんだけど32bitで_thiscallを関数ポインタ経由で呼ぶことってasm使わないと不可能? メンバ関数を関数ポインタ変数とすることは出来てもそこから第一引数にインスタンス入れたりしてもコンパイル時エラーになる
43 名前:デフォルトの名無しさん [2023/11/09(木) 18:09:02.18 ID:vDu6brxv0.net] >>42 メンバ関数をポインタ経由で呼び出したいってことならstd::bindでできるはず
44 名前:はちみつ餃子 mailto:sage [2023/11/09(木) 18:24:20.63 ID:viBVvDAP0.net] VC++ のことは知らんけどメンバ関数ポインタは関数ポインタより大きい実装になってる処理系がある。 メンバ関数ポインタを関数ポインタに変換した時点で呼び出すのに必要な情報が失われているかもしれない。
45 名前:デフォルトの名無しさん mailto:sage [2023/11/09(木) 19:04:30.42 ID:YhbH7ApDM.net] MJD?
46 名前:デフォルトの名無しさん mailto:sage [2023/11/09(木) 19:13:19.18 ID:RZ9WOZDMM.net] エラーメッセージにヒントはない?
47 名前:はちみつ餃子 mailto:sage [2023/11/09(木) 19:58:26.06 ID:u3KRHVuW0.net] 基本的には言語の規定内でやるに越したことはないので無理な型変換をしないで済ませられるように出来るものならそうしたほうがいい。 どうしてもそうできない事情がある(と質問者が認識している)ならもうちょっと詳しい状況をコードで示して欲しい。
48 名前:デフォルトの名無しさん (ワッチョイ e5a7-cSrA) mailto:sage [2023/11/09(木) 21:12:03.97 ID: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) mailto:sage [2023/11/09(木) 21:28:58.67 ID:Op1F6lz40.net] てかググったら簡単なシミュレーション方法載せてるブログあった _fastcallで宣言して第二引数のedxを捨て駒にする事で疑似_thiscallになる つまりint(__fastcall * pFunc)(CDate*, void*, int)とすれば一応アセンブラ的な辻褄は合う事になる
50 名前:デフォルトの名無しさん mailto:sage [2023/11/12(日) 10:07:59.74 ID: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 名前:はちみつ餃子 mailto:sage [2023/11/12(日) 11:02:37.63 ID:O0gb6uIB0.net] >>50 A1. 単に auto としたときに参照になることはない。 参照として受け取りたい場合は auto& にせねばならないというのは正しい。 A2. 参照かどうかで自動的に場合分けして欲しいなら decltype(auto) とすればいいが…… 参照で受けるのが正しい状況なのかどうかは状況による。 テンプレート内など自動的な場合分けが必要な場合を除いては参照は参照として明示したほうがよくない? (個人的感想です。) A3. いくつか用意されている operator<< の基本的なオーバーロードの内で bool にマッチするから。 void* もあるのだけれど C++ では任意のポインタは void* へは暗黙の型変換されないのでマッチング候補にならない。 アドレスとして解釈して欲しいなら void* へ明示的に型変換しないといけない。
52 名前:はちみつ餃子 mailto:sage [2023/11/12(日) 11:38:27.18 ID:O0gb6uIB0.net] ごめん。 間違いがあった。 ポインタは void* へ暗黙に変換できる。 この変換はオーバーロード解決時の候補になりうる。 ただ、 bool への変換とは優先順位に差がある。
53 名前:デフォルトの名無しさん mailto:sage [2023/11/12(日) 11:42:25.19 ID:j2Y95IYf0.net] >>51 >>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 名前:デフォルトの名無しさん mailto:sage [2023/11/12(日) 11:46:29.61 ID:j2Y95IYf0.net] >テンプレート内など自動的な場合分けが必要な場合を除いては参照は参照として明示したほうがよくない? 非constなら考えるがこの場合foo()はconstオヌジェクトと参照を返してくるし、 これはもうdecltype(auto)一択で良いような気がが、
55 名前:はちみつ餃子 mailto:sage [2023/11/12(日) 12:07:32.76 ID:O0gb6uIB0.net] volatile を追加する変換は出来るが除く変換は出来ないから volatile 付きのオーバーロードを用意していない operator<< では候補から消えて bool だけが候補として残ってしまうってことになるみたいだな。 volatile が付いていない場合は void* への変換のほうが bool への変換より優先順位が高いので そっちが呼ばれる。
56 名前:デフォルトの名無しさん (ワッチョイ 1fcc-mzjy) mailto:sage [2023/11/13(月) 00:27:59.42 ID:G429czY+0.net] Tiktok LiteでPayPayやAmazonギフトなどに交換可能な4000円分のポイントをプレゼント中! ※既存Tiktokユーザーの方はTiktokアプリからログアウトしてアンインストールすればできる可能性があります。 1.SIMの入ったスマホ・タブレットを用意する 2.以下のTiktok Liteのサイトからアプリをダウンロード(ダウンロードだけでまだ起動しない) https://lite.tiktok.com/t/ZSNfGY43n/ 3.ダウンロード完了後、もう一度上記アドレスのリンクからアプリへ 4.アプリ内でTiktokで使用してない電話番号かメールアドレスから登禄 5.10日間連続チェックインで合計で4000円分のポイントゲット ポイントはPayPayやAmazonギフト券に交換可能! 家族・友人に紹介したり通常タスクをこなせば更にポイントを追加でゲットできます。
57 名前:デフォルトの名無しさん mailto:sage [2023/11/13(月) 02:33:43.38 ID:eLF59GiN0.net] >>56 案内サンクス
58 名前:デフォルトの名無しさん (ワッチョイ 1f01-XI6K) [2023/11/14(火) 02:19:13.60 ID:DkCdWP9x0.net] CLion使ってる人いますか?
59 名前:デフォルトの名無しさん (ワッチョイ 1fad-XI6K) [2023/11/17(金) 17:16:02.48 ID:TT3SJP5h0.net] 日本人の死亡者が増えてるのに、メディアは報道規制 https://kizuna.5ch.net/test/read.cgi/cafe50/1699777256/l50 sssp://o.5ch.net/224t1.png
60 名前:デフォルトの名無しさん (ワッチョイ 6ecf-ekUX) mailto:sage [2023/11/18(土) 16:16:09.27 ID:5MckQHFy0.net] ラムダの参照キャプチャってconst参照に指定できないんだっけ?微妙に不便だな。
61 名前:デフォルトの名無しさん mailto:sage [2023/11/18(土) 20:47:45.62 ID: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 名前:デフォルトの名無しさん [2023/11/26(日) 06:27:21.37 ID:DSb557XU0.net] C++20 RangesはMicrosoftの説明がわかりやすかった
63 名前:デフォルトの名無しさん mailto:sage [2023/12/05(火) 10:33:06.64 ID:HLoKrA0o0.net] ふと今更思ったんだけど ポインターpに対して演算子*が返す*pは、 値じゃなくて参照?
64 名前:デフォルトの名無しさん mailto:sage [2023/12/05(火) 11:05:15.15 ID: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 名前:デフォルトの名無しさん [2023/12/05(火) 11:09:19.91 ID:IVr4NrBA0.net] >>63 参照ってのが何を意味しているか分からんが 普通はポインターの示す場所の内容だ
66 名前:はちみつ餃子 mailto:sage [2023/12/05(火) 11:22:18.93 ID:z5PiblaY0.net] >>63 ポインター p に対して *p とした場合の型は参照ではない。 たぶん >>64 は *p が参照と言いたいつもりで書いているんだと思うけど decltype に与えられる式の型が T 型の lvalue だった場合には T& が返されるルールなので その式が参照でなくても参照が返されることがある。
67 名前:はちみつ餃子 mailto:sage [2023/12/05(火) 11:24:42.01 ID:z5PiblaY0.net] あ、ごめん。 完全に間違った説明してたわ。 忘れて……。 恥ずかしい。
68 名前:はちみつ餃子 mailto:sage [2023/12/05(火) 11:34:00.06 ID:z5PiblaY0.net] と思ってよく仕様を読んでみたらやっぱりこの (>>66 ) 考え方で正しいはず。 式が識別子式の時に限っては decltype は参照にならず式の型そのままで返すせいで decltype(value) は参照にならないが、 value と *p は型システム的にも値カテゴリ的にも同じだわ。
69 名前:デフォルトの名無しさん mailto:sage [2023/12/05(火) 12:43:28.97 ID:E3GJtsiR0.net] >>68 なるほどー! 横からだが勉強になった
70 名前:デフォルトの名無しさん mailto:sage [2023/12/05(火) 12:48:03.77 ID:E3GJtsiR0.net] 巷のスマートポインタはoperator*で参照型を返すので 生ポインタも同じかと思ってたよ
71 名前:はちみつ餃子 mailto:sage [2023/12/05(火) 13:28:25.92 ID:z5PiblaY0.net] 互換性の都合とかがあるから仕方ないね。 場合分けが大量にあって単純な一般原則の組み合わせにはなってないから仕様を読み解くのがしんどい……
72 名前:デフォルトの名無しさん mailto:sage [2023/12/11(月) 15:17:51.77 ID: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 名前:デフォルトの名無しさん mailto:sage [2023/12/11(月) 15:22:02.06 ID:F1R6HyeLM.net] >>72 ラムダ式使った方が良いと思うけど本当にラムダ式なしが良い?
74 名前:デフォルトの名無しさん mailto:sage [2023/12/11(月) 15:29:19.94 ID:7vxydTfj0.net] 使われると、ラムダ式の質問をすることになると思います・・・
75 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 9f3e-pD6R) mailto:sage [2023/12/11(月) 15:45:20.57 ID:wAhsIAfi0.net] >>72 もし C++20 を使えるなら (std::sort と違って) std::ranges::sort では比較関数とは別に 比較すべき要素を取り出す操作をプロジェクションとして与えることが出来るから これ一発でいけてだいぶん楽できる。 std::ranges::sort(bs, compA, &B::a);
76 名前:デフォルトの名無しさん (ワッチョイ d701-Qbcu) mailto:sage [2023/12/11(月) 16:01:10.52 ID:dil4ai7q0.net] >>75 すげ! 今そんなのあるんやね
77 名前:デフォルトの名無しさん mailto:sage [2023/12/11(月) 16:34:20.59 ID: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 名前:デフォルトの名無しさん mailto:sage [2023/12/11(月) 17:14:54.00 ID:cVrrslE50.net] >>75 >>77 お二方、ありがとうございます 参考にして組んでみます
79 名前:はちみつ餃子 mailto:sage [2023/12/11(月) 17:25:04.51 ID: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) mailto:sage [2023/12/11(月) 22:08:32.24 ID:cVrrslE50.net] >>79 求めていたものそのものであったため、採用させていただきました ありがとうございます
81 名前:デフォルトの名無しさん mailto:sage [2023/12/20(水) 23:47:12.14 ID:tqHuIeXr0.net] int x; std::cout << x; でxが正ののときは「+」符号を付けさせるのってどうするんでしたっけ…… cout.form("%+d", x)とか以外で
82 名前:デフォルトの名無しさん mailto:sage [2023/12/20(水) 23:58:48.32 ID:Qfvbx0VO0.net] cout << showpos
83 名前:デフォルトの名無しさん (ワッチョイ 1663-4if3) mailto:sage [2023/12/21(木) 08:41:44.38 ID:6wjPSKlj0.net] てきました㌧クス、 iosヘッダで探せば良かったのか、、、
84 名前:デフォルトの名無しさん mailto:sage [2023/12/21(木) 20:01:46.13 ID:i16TeC3D0.net] C++23だとこれ std::print("{:+}", x);
85 名前:デフォルトの名無しさん mailto:sage [2023/12/22(金) 13:56:54.85 ID:pQLEje080.net] PythonやC#のようなf"{x}"構文が作られる事はないんだろうか
86 名前:はちみつ餃子 mailto:sage [2023/12/22(金) 14:54:27.15 ID:gr/vrzoo0.net] >>85 リフレクションが充実すればその上に実装できるので 直接的な言語機能として用意すると 辻褄合わせが後で面倒になるだろうし、 現時点で考えるのは時期尚早だと思う。
87 名前:デフォルトの名無しさん mailto:sage [2023/12/24(日) 17:42:14.24 ID: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 名前:デフォルトの名無しさん mailto:sage [2023/12/24(日) 17:42:52.36 ID:foDTiHm90.net] グローバル変数渡しは最初に思いつくのですが、ostringstream os1, os2とFoo obj1, obj2に対して異なるスレッドで os1 << custom_setw(30) << obj1; // スレッド1 os2 << custom_setw(20) << obj2; // スレッド2 とかやったら詰むし std::setw()とか一体どうやってるんじゃ……
89 名前:はちみつ餃子 mailto:sage [2023/12/24(日) 18:05:55.09 ID:SfA3xmSz0.net] >>87-88 特定の型を出力するときにだけ作用する書式を設定するマニピュレータってこと? std::setw がやってるのはストリームのメンバ関数 width を呼ぶのと同じ。 ストリームのオブジェクトが幅に関する情報を保存するデータメンバを持っていて、それを変更してる。 もちろんあなたが定義した独自の型 (この例では Foo) に結び付いた書式を保持するところなんて存在しないから単純にはできない。 私が思いつくのは ・ ストリームのほうも新しいものを定義する、つまり basic_ostream を継承して Foo 用の書式を格納するデータメンバを増やす ・ ストリームに対応付いたデータを格納するものを std::map かなんかで保持しておいて Foo を出力するときはそれを参照する ということくらいかな。 スレッドが絡むと面倒くさいけど、しょうがないね。
90 名前:デフォルトの名無しさん mailto:sage [2023/12/24(日) 19:04:41.48 ID:vbUOIudY0.net] 既存のcoutとかstringstreamとかで使いたいなら、グローバルのstd::unordered_map<std::ios_base*, MyManipData>にでも置いとくしかないだろうね ストリームオブジェクトの状態で持たせるクソ設計が悪いんだ
91 名前:デフォルトの名無しさん mailto:sage [2023/12/24(日) 19:34:37.93 ID: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 名前:デフォルトの名無しさん mailto:sage [2023/12/24(日) 19:35:17.01 ID:foDTiHm90.net] // 使い方 Foo obj; cout << FooWrp(obj, 10); ダッサwwwwwwwwwwwwwwwwwww しかし、「たかが表示の整形」のために排他制御しつつmapを弄ったりTLSの利用を考えるのもアレなのでこれはこれで仕方が無いのか、orz
93 名前:デフォルトの名無しさん [2023/12/24(日) 19:45:29.51 ID:Y8qSN/i/0.net] ストリーム用の演算子なんか作らずに オブジェクトの文字列表現を返す関数を用意したほうが汎用性高くない?
94 名前:デフォルトの名無しさん mailto:sage [2023/12/24(日) 19:50:06.00 ID:foDTiHm90.net] Foo obj; std::string s = obj.str(10); // 10億ギガ文字 cout << s; 出力を完遂できるんかこれ……
95 名前:はちみつ餃子 mailto:sage [2023/12/24(日) 20:00:55.29 ID:SfA3xmSz0.net] C++20 からは std::formatter を特殊化して書式指定を解釈するコードを入れておけば std::format で独自の型を表示しようとしたときにその特殊化が使われる仕組みになってる。
96 名前:デフォルトの名無しさん [2023/12/24(日) 21:41:50.00 ID:Y8qSN/i/0.net] オブジェクトの文字列表現が10億ギガ文字もあるの!? FooWrpオブジェクトをうっかりログに出力しちゃったら大変だね!!
97 名前:デフォルトの名無しさん (ワッチョイ cf63-nyJS) mailto:sage [2023/12/29(金) 19:34:46.18 ID:MPSeCS+O0.net] 実験せずに質問するますが、 int a, b; cin >> &x >> &y; に対し、 Q1. 「100 a」を入力したら例外もタイムアウト待ちも発生せず、cin.fail()がtrueになるだけ? Q2. 「100」とだけ入力してそのまんま(リダイレクト元のファイルハンドルか何かが タイムアウトもエラーもクローズもしなければ)ならそれっきり返ってこない?
98 名前:デフォルトの名無しさん (ワッチョイ cf63-nyJS) mailto:sage [2023/12/29(金) 19:40:39.84 ID:MPSeCS+O0.net] EOFが抜けてたorz Q2のケースにおいて「100 [EOF]」なら(多分)cin.fail()でとりあえずすぐ返ってくるのかそうか、
99 名前:はちみつ餃子 mailto:sage [2023/12/29(金) 21:37:06.10 ID:0cvltfsQ0.net] >>97 実にしょうもない確認なんだけど、 言いたいことは int x, y; cin >> x >> y; でよいんだよね?
100 名前:デフォルトの名無しさん (ワッチョイ de63-J7+h) mailto:sage [2023/12/30(土) 05:42:41.89 ID:3ksfrMrT0.net] >>99 >int x, y; >cin >> x >> y; おk スマンカッタorz エラーとEOFのどちらかを検知したかったら!cin.good()が正しいっぽい? https://blog.emattsan.org/entry/20110819/1313743195 ここまでは分かった気がするが、 ストリーム入力演算子std::istream& operator>>(std::istream& os, Foo& obj)の中で入力に失敗した場合 どうやってエラーを呼び出し元に通知したらええんじゃ……
101 名前:デフォルトの名無しさん mailto:sage [2023/12/30(土) 05:50:37.02 ID: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) mailto:sage [2023/12/30(土) 08:47:16.28 ID:XV37Te4m0.net] >>100 ストリームのフラグを立てるメンバ関数は setstate だけど >>101 の状況ならフラグはもう立ってるから戻るだけで問題ないよ。
103 名前:デフォルトの名無しさん mailto:sage [2023/12/30(土) 13:48:41.88 ID:3ksfrMrT0.net] わかりた ていうかエラー判定(eofbit以外のビットのセットを判定)なら!os.good()や!os.goot()ではなくて os.failed()か!osですたね……orz これらに関して追加の質問が出たら初心者スレに書くわサーセン;;;
104 名前:デフォルトの名無しさん mailto:sage [2023/12/31(日) 20:09:05.68 ID:tpduSr4A0.net] class A{ char buf_[size]; } このbuf_に任意のオブジェクトをplacement newして使用するのだけど このオブジェクトをコピーしたりムーブする場合、単純にコピー元のbuf_からコピー先のbuf_にmemcopyしてしまって大丈夫ですか?
105 名前:デフォルトの名無しさん mailto:sage [2023/12/31(日) 20:44:02.18 ID:bvEcnWMM0.net] 全く大丈夫じゃない 初心者スレからどうぞ
106 名前:デフォルトの名無しさん mailto:sage [2023/12/31(日) 20:54:11.90 ID:NNsdlVTY0.net] 構造体から派生させれば出来るよ
107 名前:デフォルトの名無しさん mailto:sage [2023/12/31(日) 21:04:16.47 ID:bvEcnWMM0.net] せめてPODと言おう 初心者スレからどうぞ
108 名前:はちみつ餃子 mailto:sage [2024/01/01(月) 00:18:02.48 ID:6hyMwo3D0.net] POD は削除された。 trivially copyable の要件を満たすならその型は memcpy でコピーしてもよい。 std::is_trivially_copyable で判定できるのでどこかに制約を入れておけば安心かもね。
109 名前:デフォルトの名無しさん mailto:sage [2024/01/01(月) 00:36:03.09 ID:an53Mx2V0.net] 削除されたんですか?(バージョンいくつで?) c++20 で非推奨になった、てのはすぐ調べられたんだけどその先が分からんです
110 名前:はちみつ餃子 mailto:sage [2024/01/01(月) 00:46:07.42 ID:6hyMwo3D0.net] >>109 規格の文面としては C++20 で POD はもう削除されていて POD の概念を使わない形で再編されてる。 std::is_pod はまだある (非推奨) からこれが POD の定義だという意味ではまだあるとも言えるけど。
111 名前:デフォルトの名無しさん mailto:sage [2024/01/01(月) 00:46:34.65 ID:l/ylj5kb0.net] アライメント忘れてるぞ
112 名前:デフォルトの名無しさん (ワッチョイ e1f0-JZT3) mailto:sage [2024/01/01(月) 03:01:35.02 ID:5pNbZa2B0.net] >>104 まず自分でコード書いてみ よろしくないところは指摘してやるから
113 名前:デフォルトの名無しさん (ワッチョイ 8101-KEYj) mailto:sage [2024/01/01(月) 03:14:22.37 ID:8zoq4UeO0.net] オワコン名称出してマウント。プークスクス
114 名前:はちみつ餃子 mailto:sage [2024/01/01(月) 03:40:47.98 ID:hmX3WjmM0.net] POD が削除されたかどうかは重要ではなくて、 POD より弱い制約 (trivially copyable) で memcpy が許されるというのが主旨。 その点は C++11 からそうなってる。
115 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 823e-OTTg) mailto:sage [2024/01/01(月) 04:06:49.46 ID:hmX3WjmM0.net] 「構造体」ってのも C++ 用語的にはイケてないと思うよ。
116 名前:デフォルトの名無しさん [2024/01/01(月) 04:55:26.71 ID:e5pnn2Xx0.net] アライメントは基本型のどれかと同じアライメント制約に合わせれば良いいということなら 使おうとしているうちで最も厳しいアライメント制約に一致する基本型を含むunionで解決するというのがC言語における伝統的な手法という印象、 C++でunionにしたら(それが可能なメンバのみなら) memcpyは安全とかにはならない?
117 名前:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 823e-OTTg) mailto:sage [2024/01/01(月) 05:30:52.12 ID:hmX3WjmM0.net] >>116 コンストラクタや代入演算子がトリビアルであることなどの制約を守れば共用体も trivially copyable になりうる。 (C++ の共用体はコンストラクタやメンバ関数を定義できるがそこらが制限されることになる。)
118 名前:デフォルトの名無しさん [2024/01/01(月) 14:24:55.17 ID:kge3DGj60.net] char* と long* のコピーは?
119 名前:はちみつ餃子 mailto:sage [2024/01/01(月) 15:31:30.97 ID:hmX3WjmM0.net] ポインタも含めてスカラ型は Trivially copyable https://timsong-cpp.github.io/cppwp/n4861/basic.types#9
120 名前:デフォルトの名無しさん mailto:sage [2024/01/03(水) 23:34:38.84 ID: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 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 00:44:07.87 ID:/FDyuY0i0.net] decltype(src.*p_)ってbase_なのでダメだろう
122 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 00:58:18.81 ID:ECF9R1Fj0.net] ていうか、decltypeで型指定してるだけだからコピーもなにもされてないぞソレ
123 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 02:28:40.49 ID:oZapr/U70.net] std::anyのコードでも読んだほうが早い
124 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 09:11:56.12 ID:/FDyuY0i0.net] A::base_に以下を足してA::derived_で実装し Aのコピーコンストラクタから呼べば? virtual base_ *clone (void *p) = 0;
125 名前:デフォルトの名無しさん [2024/01/04(木) 13:26:37.40 ID:1KQpMTCj0.net] void*って、ポインターの先のサイズ未知だよなぁ
126 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 17:16:40.43 ID:ACseOt7T0.net] derived_かそのメンバf_の型を知るにはRTTIしかないのですかね? >>121 decltypeだと派生先の型はわからないのか >>122 実体のコピーの処理が抜けてました…
127 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 21:53:05.60 ID: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 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 22:19:16.70 ID:ECF9R1Fj0.net] derived_(F f) ←この時点でムダなコピーが1度発生していることには気付いてる?
129 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 22:21:15.81 ID:/FDyuY0i0.net] >>127 書き込む前にコンパイルしなよ
130 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 22:41:26.61 ID:Dv09vJ7A0.net] バッファの中にオブジェクトを作れたら、それで何をしたいのかが気になる
131 名前:デフォルトの名無しさん mailto:sage [2024/01/04(木) 23:21:36.86 ID:oZapr/U70.net] >>127 cloneの中ってplacement newでcopy constructorを呼ぼうとしてるんだよな? いちおうあってるけどundefined behaviorまみれ
132 名前:はちみつ餃子 mailto:sage [2024/01/04(木) 23:35:27.70 ID:td6kYpbC0.net] たぶんやりたいことは std::allocator_traits::construct なのかな