C++相談室 part164

■ このスレッドは過去ログ倉庫に格納されています
2023/05/09(火) 11:50:52.06ID:EYc2I7oW0
!extend:checked:vvvvv:1000:512
!extend:checked:vvvvv:1000:512
↑同じ内容を3行貼り付けること

次スレは>>980が立てること
無理なら細かく安価指定

※前スレ
C++相談室 part163
https://mevius.5ch.net/test/read.cgi/tech/1672409791/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
2023/06/04(日) 23:21:12.95ID:QWRuQk/m0
勉強になるなぁ
boost::lexical_cast
ばっか使ってきた
2023/06/05(月) 01:56:30.15ID:yTJt/rkc0
>>154
仕様を確認して文句つけているのだから無問題
2023/06/05(月) 02:01:37.37ID:yTJt/rkc0
つか自分のスキルに合わせて仕様を変えてしまう香具師よりはマシ
2023/06/05(月) 02:39:23.25ID:yTJt/rkc0
つか初心者スレで今教えてもらったわサーセン;;;
std::stod()の第2引数でどこまで読んだのかわかるのかそうか、、、
159デフォルトの名無しさん (アウアウウー Sac5-Rr/m)
垢版 |
2023/06/05(月) 09:40:21.73ID:ejs/048Ga
1e-3
0.4E+5

どうせ . とか + とか - とか e とか E が数字の後ろに来たらエラーにする糞オレオレ関数の出来上がり
160デフォルトの名無しさん (アウアウウー Sac5-+LPJ)
垢版 |
2023/06/05(月) 18:46:42.35ID:QlKvcf+ua
fortran爺が1e-3を1-3と書いて送ってくるの辛い
2023/06/05(月) 22:24:29.81ID:yTJt/rkc0
charやwchar_tのうちは文字数くれたら別段間違うことは無いはず……
162デフォルトの名無しさん (ワッチョイ 916e-UlWg)
垢版 |
2023/06/06(火) 05:24:35.89ID:sRXlIYgz0
0xe5a3ec05p-10
2023/06/07(水) 18:16:46.44ID:yJ6NJbScM
regex 使って、全角半角タブはreplace
しつつも、正規表現で、数字だけ残して
ってしたらいいのでは
2023/06/07(水) 19:51:43.45ID:Y1IkEaDo0
ファイル名で並び替えるとき数字を文字列じゃなく数として判断して並び替えるの便利だよね。StrCmpLogicalWみたいなの
2023/06/07(水) 20:17:49.58ID:Wtu+kJ5G0
digitntegerみたいな関数なかったっけ
javaと混同してるかもしれん
2023/06/07(水) 20:48:56.87ID:DVJV7mYE0
大文字小文字とか小数とか半角全角とか漢数字とかあるから闇が深い
2023/06/07(水) 21:25:16.49ID:nzVrXgF60
アンダーバーの位置関係も結構罠だよね
文字コード的には 大文字<アンダーバー<小文字 だから
2023/06/07(水) 23:13:43.57ID:ZHL7BfYmM
言語+コンパイラの仕様が拡張してるのにライブラリは貧弱なまま
自己流に実装してしょうもないバグが紛れ込む

関係ないけどstd::stodはC言語版と微妙に仕様が違うのだろうけどそんなの調べてない
2023/06/08(木) 00:14:20.61ID:mm4FKY9+0
例えばstodが解釈できる数値表現を正規表現でも解釈したいと思ったらどうしたら
170デフォルトの名無しさん (アウアウウー Sac5-tVFH)
垢版 |
2023/06/08(木) 11:09:51.53ID:rxjbLVG0a
仕様の不備は運用でカバー
2023/06/09(金) 00:34:29.94ID:Y9bb1A2p0
std::sort (std::execution::par, v.begin(), v.end());
上記で並列ソートできるとのことですが何並列なんでしょうか?
もし環境に合わせて良きに計らってくれるのなら
その良き並列数を取得する関数などありますか?
2023/06/09(金) 01:32:53.73ID:vjFKJkM00
>>171
詳細は言語仕様では規定されていない。
リソースが不足していれば並列化されないこともあり得る。
並列化は大抵の場合に OS のサポートが必要だし
どういうサポートがあるかわからんので言語として明瞭な規定を決められない。

並列化される保証はないのにデータ競合が発生しないように実装するのは
プログラマの責任なので若干の理不尽さを感じなくもないが
C++ ってのはそういうもんなので……。
2023/06/09(金) 07:16:14.12ID:bBOCrSG+0
週末のレイトレーシングで1-17あたりをマルチスレッドにしてみたんだけど、ubuntu上でg++やインテルコンパイラだとスレッド数を増やすと逆におそくなるんです。windows上でvisualstudioでコンパイルすると、望み通りスレッド数を増やすほど速くなりました。何でなんでしょう?
2023/06/09(金) 08:07:59.94ID:e2G6/2re0
>>173
>週末のレイトレーシングで1-17
全く意味がわからないんだが?
>何でなんでしょう?
お前のコーティングのせいじゃないか?
2023/06/09(金) 08:18:32.57ID:m5f79nsG0
gccはね・・・どうも平行/並列処理には本気じゃないところがある
たとえばstd::execution::parなんか真面目にやらんかこらって言いたくなる
2023/06/09(金) 08:19:05.88ID:m5f79nsG0
無料なので強く出られないけどね
2023/06/09(金) 11:49:37.37ID:Y9bb1A2p0
皆さんレスを有り難うござます
うちはstd::execution::parで効果絶大です
$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2023/06/09(金) 22:45:32.96ID:uysUozYZ0
なるほどなあ
2023/06/10(土) 02:07:59.33ID:oiDhCbH60
EASTLが久しぶりにバージョンアップしたね
2023/06/10(土) 07:02:46.03ID:kaZ6v5kb0
ほう!いいね
2023/06/14(水) 07:54:14.73ID:/jeWb7sY0
time コマンドで調べたメモリの使用量 (max resident set size) が理論値よりも多くて、原因を特定するためにコード内の各箇所でその時点でのメモリ使用量を出力できたら良いなと思います。
実行環境は Linux なのですが、どのようにするべきでしょうか?
2023/06/14(水) 08:43:22.06ID:/jeWb7sY0
あとメモリに関連した質問で、例えばめちゃデカい std::vector を要素数 1 に resize しても capacity はめちゃデカいままですよね?
STL コンテナ以外にも、大きいメモリが割り当てられてるオブジェクトを使用後に破棄したいというケースがよくあります。
最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが、他に、オブジェクトに割り当てられているメモリを手動で解放する方法があったら教えてください。
183デフォルトの名無しさん (スプッッ Sd33-5Oyn)
垢版 |
2023/06/14(水) 08:49:33.85ID:Xd2fVcpxd
/proc/self/stat というファイルを覗きに行くか、
getrusage というシステムコールで取得することになるかな
2023/06/14(水) 09:19:31.16ID:O3itrano0
>>182
そのために shrink_to_fit がある。
詳細は実装依存なので何もしない関数であっても仕様に反しないけど
常識的には各実行環境で効率的に動くように実装されるので
まずは試してみても損はないと思う。

アロケータを自作してもあまり制御できないんよね。
アロケーションが必要になったらコンテナからアロケータが呼ばれるという
受動的な構造なのでコンテナによるメモリ管理戦略にそれほど関与できるわけではない。

本当にどうしても標準ライブラリの挙動の詳細が不満なら
自分で同等のものを実装する (または望ましいものをどこかから見つける) しかないよ。
2023/06/14(水) 10:15:22.04ID:iWYHYN4ra
>>182
new で造って delete (または delete []) で解放
2023/06/14(水) 12:28:17.37ID:XWt8afSz0
更にいうと、deleteはgccでは推奨されないのでptrを使うよりはstaticもしくはvirtualを使いましょうね。
2023/06/14(水) 12:29:45.65ID:XEzvAdInM
>>182
>>185とほとんど同じだけどunique ptrで管理。
ヒープの確保時間が問題になるならアロケーター使ってヒープを予約する。
2023/06/14(水) 13:12:37.90ID:9CAXVpD30
>>182
vector<空にしたいオブジェの要素の型>().swap(空にしたいオブジェ)
2023/06/14(水) 13:33:02.07ID:iWYHYN4ra
>>188
vector<空にしたいオブジェの要素の型> hoge;
が既にあったとしたら
vector<空にしたいオブジェの要素の型>(hoge).swap(hoge);
で良いらしいけど副作用の心配無い?
2023/06/14(水) 14:03:16.39ID:0kIiqVrM0
>>183
ありがとうございます
> getrusage
を試してみようと思います

>>185-187
STL コンテナを使うとしても自作クラスを使うとしても、オブジェクトを unique_ptr で持つことにして要らなくなったら reset() すれば確保していた分のメモリを捨てられるということでしょうか
依存関係が絡み合っていて簡単に小さいスコープに分割できないときは試してみようと思います
2023/06/14(水) 14:16:54.18ID:iWYHYN4ra
reset()は違うと思う
2023/06/14(水) 14:26:34.51ID:HNZbb8Sq0
>>189
その場合はメモリアクセス領域が変わるのでswapする前に取得済みだったイテレータは再取得する必要あり
2023/06/14(水) 15:52:59.34ID:K9MvWtl90
>186 が何を言ってるのか意味不明でこわい。
2023/06/14(水) 15:54:13.97ID:K9MvWtl90
>>191
「reset() すれば確保していた分のメモリを捨てられる」で間違いないでしょ。
2023/06/14(水) 18:26:24.05ID:9LyNOs9uM
>>190
resetする必要は無いよ。

コンテナから普通に要素を削除すれば、後はコンテナクラスがよろしくやってくれる。効率は実装次第だけど。
2023/06/14(水) 18:51:34.14ID:0kIiqVrM0
>>195
コンテナクラスがよろしくやってくれるのに任せるのであれば、スマートポインタで持たずに単にコンテナとして持つのと変わらないように思うのですが、違うのでしょうか。
ちゃんと理解していなかったら申し訳ありません。
2023/06/14(水) 18:58:01.98ID:vjajEcDc0
vectorを信頼するなら単にclear()してshrink_to_fit()すればいい
信用できないならスマポで持っといていらなくなったら手動でブチ消せばいい
それすら信用できないならイチから自分で作れ
お前がどれだけ心配消化による
2023/06/14(水) 19:18:20.42ID:YeSwNDrrM
>>196
どのコンテナを使うかによる。

vectorとかdequeはまだ確保していない要素用の領域をしばしば予約するから、>>182のような状況を回避するのは面倒臭い。

listとかmapは(これも実装次第だけど)まだ確保していない要素のための領域を予約したりしないから、他のデメリットを許容するなら>>182対策の選択肢になる可能性はある。

いずれにしても、そこまで気にするならまずベンチマークを取って実態を調査すべきだし、そもそも巨大なメモリを頻繁に確保・解放するのは設計に問題があることが多いから、メモリを解放しないで済む方法を検討してみる。
2023/06/15(木) 03:20:48.20ID:J1cG0ikp0
>>198
そもそもvectorのスマートポインタ (あるいはより一般的にサイズが動的なクラスのスマートポインタ) を作り、そのvectorやクラスのサイズを変えたときって確保されてる領域のサイズも変わるんでしたっけ?
手動で変えなきゃいけないと思っていました
(また、vectorのポインタとvectorの先頭要素のポインタは意味が違うのでよりわけが分からなくなりました)
2023/06/15(木) 06:50:20.05ID:usfnoco+0
std::vectorはshrink_to_fit()呼ばない限り勝手にcapacity縮めたりしないはずだけど
2023/06/15(木) 08:48:34.83ID:hMmgKiSo0
>>199
コンテナ内のポインタの予約は避けられないよ。

ただ、ポインタのサイズを気にするようなシビアな状況なら、そもそもc++じゃなくてcで実装することを検討すべき。
2023/06/15(木) 09:00:49.34ID:K4jCDX8M0
シビアな状況でC++が使えないやつがCならOKなはずはない
2023/06/15(木) 10:11:47.24ID:dLjlwX4ma
>>199
何が判ってないのかが判ってないパターンだな
まともな解答もらってても何が正しいのか(なぜ正しいのか)
すら判断出来なさそうなレベル
解答者に失礼
2023/06/15(木) 10:56:55.78ID:kyFBXozFF
他所スレで同じ様な流れが

>742
質問の仕方が悪いだけwww
欲しい情報を引き出すには一定以上の質問能力が必要

>743
質問の仕方が重要なのはその通りだけど
ここで問題にしてるのは自分が詳しくない領域では質問の仕方が悪かったかどうかも分からないってことでしょうよ

>744
>>742
質問のしかたさえ良ければ正確な情報が手に入ると思ってるのは素人だけだぞ?w
2023/06/15(木) 12:02:49.40ID:J1cG0ikp0
>>201
いや、ポインタのサイズなんて全く気にしてない。
質問は、メモリの解放をコンテナに任せるならわざわざスマポで持つ意味ないよね? ってこと。
で、コンテナに任せるというのは元の質問(>>182)への回答に全くなってないよね? ってこと。
(その理由は>>184,200様の書いてくださってる通り)
つーかお前が何も分かってないのは>>195でreset()しなくて良いとかほざいてる時点でお察し。


>>203-204

>>203>>191で「reset()しなくても良い」とかほざいてて>>195と同レベ。


>>183-185,194,197,200様
ご丁寧な回答をくださりどうもありがとうございました。
勉強になります。
2023/06/15(木) 12:29:34.24ID:QcI//Xn+M
>>205
コンテナのsmart ptrの扱いは調べた?
コンテナの要素とポインタの参照先の違いについて根本的な誤解がありそう。

vectorはまだ構築していないインスタンス用のメモリ領域を予約するけど、smart ptrはそんなことしないよ。
vector<smart ptr>もsmart ptr の予約はするけど、smart ptrの参照先インスタンスの予約はしない。
2023/06/15(木) 13:15:56.80ID:J1cG0ikp0
>>206
だから、結局任意のコンテナ、クラスに対してスコープ内でメモリを解放する方法は?
new で生ポを持って delete するか、スマポを持って reset するかだろ?


> vectorはまだ構築していないインスタンス用のメモリ領域を予約するけど、smart ptrはそんなことしないよ。
そりゃそう。
ゆえに、メモリを間違いなくリリースしたいなら reset すればよいのですねと>>190で述べている。
それで終わりなのにお前と来たら reset は不要だの元のコンテナの挙動に任せるだの、論旨を全く理解してないとんでもレスばっかり。


> vector<smart ptr>も……
論外。
誰もスマポのvectorの話なんてしてねえ。
2023/06/15(木) 14:56:16.78ID:M9bt3STi0
186でも言ってるがstaticもしくはvirtualでデストラクタ使えよ
それがシンプルで高速で1行も無駄のない設計な
2023/06/15(木) 15:01:28.21ID:B8g22vaD0
182の
>最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが
がコンストラクタで確保してデストラクタで消す話というのはわかってる上で

>他に、オブジェクトに割り当てられているメモリを手動で解放する方法があったら教えてください。
なんじゃないの?

そんなものは無いっていう答えもあるにはあるけどサ
2023/06/15(木) 18:41:07.51ID:QIwD56Ju0
最近IPP触り始めたんですが全部飽和演算で面食らってます
Modulo関数は無いんですか?
2023/06/15(木) 21:00:11.51ID:W1C5TI4i0
>>207
ああ、ごめん。めっちゃデカイインスタンスのvectorじゃなくて、めっちゃデカイvectorね。
それなら実装依存だけど>184か、>192とか参照無効化の制限とかコピーコストとかあるけど>189。189はsmart ptrにしとけば実用上問題ないかね。vectorのイテレーターは保存するものじゃないし。
2023/06/15(木) 21:28:08.23ID:3cvhbwG+0
実際の所、vectorならclear()→shrink_to_fit()でメモリが開放されないこってありうるの?
2023/06/15(木) 22:10:40.95ID:usfnoco+0
規格上はshrink_to_fit()にメモリ解放する義務はないし、実装定義で何やっても自由(capacityを増やすような真似だけは禁止)
shrink_to_fit()がなんにもしない実装でも一応規格準拠になる
そんな糞みたいな実装が実在するかは知らない
2023/06/16(金) 02:13:28.00ID:PZdB0bgSH
>>211
はい結局一人だけ違う話してた
ハァァ~~~~~(クソデカため息)
2023/06/16(金) 11:31:25.61ID:QEmhRLek0
>>212
基本的には効率的に実装されるものだと信じて良いと思うが
どういう実装が効率的であるかは実行環境の事情による。

たとえばメモリ管理がページ単位というのは普通のことだし
その場合にページ単位より細かく確保したり解放したりしても非効率になる。

常に何もしないというような実装はあまりないと思うけど
解放するほうが非効率だと考えられる状況では
shrink_to_fit を呼んでも解放しなかったり部分的にだけ解放する
ということはそれなりにあり得そうだと思うよ。
2023/06/16(金) 12:08:14.46ID:nWXjt7Za0
capacityと OS側からみた空きメモリはまた別かもしれんわけで
アロケーターがOSからじかに要求してる場合もあれば
OSへの要求回数を減らして内部でプールしてやりくりしてるのもあるし
制御したいレイヤーによっては全部自前でやるしかない という落ちにも
2023/06/16(金) 12:26:43.83ID:B2wRJ7jC0
>>215
まぁ、細かい単位のメモリだったら、実際に開放されているかどうかなんて、ほとんど動作に影響しないとも言えるしね
(未初期化変数の不具合が発覚しづらい、くらいか)
とりあえずshrink_to_fitを呼んでおいて、細かいことは気にしないのが一番かもしれないw
2023/06/16(金) 12:46:08.57ID:H6XPX5qB0
「STLコンテナ以外にも」という文言が読めてない文盲さんたちがvectorの話ばっかしててワロ
2023/06/16(金) 15:41:25.79ID:KX+TErXo0
「STLコンテナ以外にも」はSTLコンテナも含むということ
STLコンテナの話をしても何もおかしくない
2023/06/16(金) 15:43:23.81ID:ly+Q1cW8a
いつものことだが
ほんの最初の数レスで終わってるのに
どうでも良い脱線ほど盛り上がってgdgdレスでスレが延びる
2023/06/16(金) 15:46:42.75ID:/DJegtL/a
ほんそれ
回答終了してんのにちんこかゆい
222デフォルトの名無しさん (スフッ Sd33-pDI4)
垢版 |
2023/06/16(金) 15:49:19.69ID:YNpYq5+wd
>>182 良く読むと
>STL コンテナ以外にも、大きいメモリが割り当てられてるオブジェクトを使用後に破棄したいというケースがよくあります。
>最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが

いやいやそもそも「関数とか局所的なスコープ(つまりautoだろ?stackだろ?)で大きいメモリ確保しようなんて思うな」って話なんだよな
2023/06/16(金) 16:09:01.10ID:qgM8i0iT0
ローカルなvectorを置けばヒープ確保されるので「つまりautoだろ?stackだろ?」は
また何か誤解してる人が来たなとしか。
2023/06/16(金) 16:49:22.15ID:ybGonaVE0
reset要らないとか言ってる奴らは結局何なん
2023/06/16(金) 19:32:47.80ID:yx9ngvFiM
>>224
結論は>211にまとめといた。
resetは要らん。
2023/06/17(土) 08:56:51.34ID:3MnK6eEg0
>>223
「STLコンテナ以外にも」という文言が読めてない文盲さんたちがvectorの話ばっかしててωωω
2023/06/17(土) 10:36:04.78ID:koF9X0k9M
>>226
「大きいメモリが割り当てられてるオブジェクトを使用後に破棄したい」なら
>185か>187。
>187はunique ptrの置き場所と解放タイミングによって解放の仕方が違って、自動変数にして関数やスコープから抜けるタイミングで解放するなら手動操作不要、vectorなどのヒープに置くとかスコープの終わり前に解放したいとかならreset()とかvectorの要素削除とかで手動解放。

いずれにしても、自動変数に巨大インスタンスを考え無しに置くのは悪手で、そのオブジェクトがスタックに巨大データを置かない(ヒープ等に置く)ことを確認してからにしたほうがいい。
2023/06/17(土) 15:30:36.02ID:S+64vkUJ0
>>216
vectorのcapacityはそのvectorが氏ぬかcapacity縮小アクションが生じない限りvector固有に占有されるから
capacity(のうちsize()を超える分)と OS側からみた空きメモリはまた別でケテーイ……
一方malloc()がOSからゲットしたメモリをOSに返さずにいるのはOS側からみた空きメモリではないにしろ
同一プロセス内の他のオブジェクトの構築に使えるのだから空きメモリのうち
これすらもOSに返したいということならこの流れの中で現状答えがでていないキモヌ
2023/06/17(土) 15:31:34.82ID:S+64vkUJ0
まあしいて言えばプロセスを一旦exitして再立ち上げ?
2023/06/17(土) 15:45:09.56ID:S+64vkUJ0
普通に作ったら(コードで明示的に直接OSのAPIでメモリを分捕って解放とかしない限りは
プロセスのprivate bytesはプロセスが氏ぬまで増えることはあっても減ることは無いという印象、
2023/06/17(土) 16:27:35.20ID:5e+acAEX0
>>225
スマンまじで理解できないのだけど、なぜvectorに限った話をしてるの?
2023/06/17(土) 19:22:00.09ID:mYwWSuEFM
>>231
巨大インスタンスは>227
2023/06/17(土) 19:29:36.10ID:HtrmHz3i0
回答者のレベル低いな~~~
こんだけダラダラ続けて、結局質問者>>182>>190で早々に結論づけてることをリピートしてるだけw
2023/06/17(土) 19:54:50.95ID:9hSxsWrs0
アロケータ気に入らないなら自作くらいしろよポンコツ
なにもかもSTLに頼りやがってそれでPGやってるつもりになるなよ
2023/06/17(土) 20:19:47.36ID:S+64vkUJ0
人類には早すぎた話題また……
2023/06/17(土) 23:14:07.63ID:H9lc23A5M
次世代の人は便利に使いこなしてるかより簡素になった仕組みを使うのだろう
2023/06/18(日) 03:00:55.26ID:GIMFAM+a0
>>231
コンテナの種類を問わない一般的な方法なんてものはないからじゃないですかね
2023/06/18(日) 21:04:45.70ID:VwYqKwPk0
以下のコードでaccumulateのとこでコンパイルエラーが起こります
何故か分かります?
#include <iostream>
#include <array>
#include <deque>
#include <exception>
#include <numeric>
using Vector = std::array <double, 3>;
using Vector_Container = std::deque <Vector>;
Vector &operator += (Vector &lhs, const Vector &rhs) {
const auto size {lhs.size ()};
if (size != rhs.size ()) throw std::runtime_error ("Sizes are different.");
for (size_t i {0}; i < size; ++ i) lhs [i] += rhs [i];
return lhs;
}
Vector operator + (const Vector &lhs, const Vector &rhs) {
Vector result {lhs};
result += rhs;
return result;
}
int main () {
Vector v0 {0, 1, 2}, v1 {10, 11, 12};
Vector_Container c0 {v0, v1};
accumulate (c0.begin (), c0.end (), Vector {}); // コンパイルエラー
return 0;
}
2023/06/18(日) 21:45:44.90ID:UCXMUPHB0
>>238 エラーメッセージ見ればたぶん分かる。
2023/06/18(日) 21:48:16.43ID:VwYqKwPk0
>>239
レス有難うございます
まず訂正
-accumulate
+std::accumulate
全部は貼れないですけど大事そうなところ

In file included from /usr/include/c++/12/numeric:62,
from test1.cpp:18:
/usr/include/c++/12/bits/stl_numeric.h: In instantiation of ‘constexpr _Tp std::accumulate(_InputIterator, _InputIterator, _Tp) [with _InputIterator = _Deque_iterator<array<double, 3>, array<double, 3>&, array<double, 3>*>; _Tp = array<double, 3>]’:
test1.cpp:22:14: required from here
/usr/include/c++/12/bits/stl_numeric.h:141:46: error: no match for ‘operator+’ (operand types are ‘std::remove_reference<std::array<double, 3>&>::type’ {aka ‘std::array<double, 3>’} and ‘std::array<double, 3>’)
141 | __init = _GLIBCXX_MOVE_IF_20(__init) + *__first;
2023/06/18(日) 23:15:51.41ID:w3/xAOT+0
ADLでoperator+が見つからないからかな?
struct Vector : std::array <double, 3> {};
みたいに定義したらいけるのでは
2023/06/18(日) 23:20:13.62ID:VwYqKwPk0
>>241
>struct Vector : std::array <double, 3> {};
>みたいに定義したらいけるのでは
通りますね
どういうこと?
243デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
垢版 |
2023/06/18(日) 23:24:52.33ID:bX3uBTIT0
std::accumulateが14行目で定義したoperator+を見つけれてないのが原因っぽい。

std::accumulateの第4引数に
[](const Vector& v1, const Vector& v2){ return v1+v2;}
を追加してやるとコンパイルは通る。

14行目のoperator+をstd名前空間に入れてやれば動くにゃ動くけど色々マズいので(調査する分にはいいけど)最終的な解答にはならないかな
244デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
垢版 |
2023/06/18(日) 23:29:04.68ID:bX3uBTIT0
>>242
たぶんC++コンパイラはoperator+の候補を検索するときに
Vector( = std::array<double, 3>)と同じ名前空間にあるものしか検索しない

Vectorのクラス定義そのものがグローバル名前空間にあるなら14行目のoperator+を見つけられるけど、
今はVectorの正体はstd::array<...>なのでstd名前空間しか検索しないんだと思う
2023/06/18(日) 23:39:19.50ID:VwYqKwPk0
>>243,244
なるほど解説頂きまして有難うございます
グローバルスコープはどっからでも見えて良さそうなものの
何でグローバルスコープの関数を探さないですかね?
246デフォルトの名無しさん (ワッチョイ a901-UvLK)
垢版 |
2023/06/18(日) 23:48:03.44ID:EGGkT3O00
独自のメンバ変数を持たないのなら継承してしまうのも手ではある(ただしコンストラクタやarrayを受け取るキャスト用コンストラクタとか書く必要が出ると思うけど)
ただ、そもそもカスタマイズしたり自分の用途に本当に使いやすいものを作りたいなら、ちゃんと自分で全部書いた方がいいと思うよ
2023/06/19(月) 00:42:02.49ID:2lgIrH6A0
>>245
std::accumlateの定義内からだと、その下の方(ユーザーコード)で定義されてるoperator+は見えてないので、グローバル名前空間の探索では見つからない
2023/06/19(月) 00:52:39.28ID:Q4g6N6uX0
>>247
std::accumlateが定義されているnumericをincludeする前に
以下のようにグローバルスコープにプロトタイプを置いても
同じようにoperator+が見えてないとエラーが出ます
using Vector = std::array <double, 3>;
Vector operator + (const Vector &lhs, const Vector &rhs);
#include <numeric>
249デフォルトの名無しさん (ワッチョイ a901-UvLK)
垢版 |
2023/06/19(月) 03:40:46.00ID:RYn53SnN0
accumlateは関数テンプレートだから実体化される時点でoperator+が見えてりゃOKのはず
言われてる通りADLで対象外なのが問題
2023/06/19(月) 05:38:23.58ID:JAsvvATP0
>>237
(スマート)ポインタで持って要らなくなったら明示的にリリースする方法はあらゆるコンテナに対して使えるよね?笑
2023/06/19(月) 08:48:03.43ID:KLBRX38t0
>>250
>>223
2023/06/19(月) 09:20:16.57ID:Q4g6N6uX0
>>249
有難うございます
グローバルスコープに定義した関数が見えないのは
どうしてなんでしょうかね?
それでは全然グローバルじゃないような気がするのですが
規格を決めるときに何か意図があったのでしょうかね?
253デフォルトの名無しさん (ワッチョイ a901-UvLK)
垢版 |
2023/06/19(月) 10:39:37.41ID:RYn53SnN0
そもそもが名前空間内(よその演算子と混ざらないように)にある演算子オーバーロードを、外部からでも引数が合えば使えるように(std::operator+(a, b)とか書かないでいいように)するためのルールらしいから
外部の演算子見に行くのは目的に合わんのじゃね

std名前空間内のarrayに外部から勝手に動作を追加しようとしてるんだから、あまりよろしくないやり方しようとしてると考えた方がいい
(だから>>246のように書いた、継承したら一応arrayではなくちゃんとVectorクラスに対する演算子だから通る)
2023/06/19(月) 11:53:54.08ID:Q4g6N6uX0
>>253
>std名前空間内のarrayに外部から勝手に動作を追加しようとしてるんだから、
>あまりよろしくないやり方しようとしてると考えた方がいい
なるほど
たぶんこういう考え方なんでしょうね
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。