!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
探検
C++相談室 part164
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん (ワッチョイ 33da-QP0H)
2023/05/09(火) 11:50:52.06ID:EYc2I7oW0185デフォルトの名無しさん (アウアウウー Sadd-g1CP)
2023/06/14(水) 10:15:22.04ID:iWYHYN4ra >>182
new で造って delete (または delete []) で解放
new で造って delete (または delete []) で解放
186デフォルトの名無しさん (ワッチョイ 8bfb-Xx8j)
2023/06/14(水) 12:28:17.37ID:XWt8afSz0 更にいうと、deleteはgccでは推奨されないのでptrを使うよりはstaticもしくはvirtualを使いましょうね。
187デフォルトの名無しさん (テテンテンテン MMeb-jufV)
2023/06/14(水) 12:29:45.65ID:XEzvAdInM188デフォルトの名無しさん (ワッチョイ d9f0-EP1b)
2023/06/14(水) 13:12:37.90ID:9CAXVpD30 >>182
vector<空にしたいオブジェの要素の型>().swap(空にしたいオブジェ)
vector<空にしたいオブジェの要素の型>().swap(空にしたいオブジェ)
189デフォルトの名無しさん (アウアウウー Sadd-g1CP)
2023/06/14(水) 13:33:02.07ID:iWYHYN4ra >>188
vector<空にしたいオブジェの要素の型> hoge;
が既にあったとしたら
vector<空にしたいオブジェの要素の型>(hoge).swap(hoge);
で良いらしいけど副作用の心配無い?
vector<空にしたいオブジェの要素の型> hoge;
が既にあったとしたら
vector<空にしたいオブジェの要素の型>(hoge).swap(hoge);
で良いらしいけど副作用の心配無い?
190デフォルトの名無しさん (ワッチョイ 219b-q0yD)
2023/06/14(水) 14:03:16.39ID:0kIiqVrM0191デフォルトの名無しさん (アウアウウー Sadd-g1CP)
2023/06/14(水) 14:16:54.18ID:iWYHYN4ra reset()は違うと思う
192デフォルトの名無しさん (ワッチョイ 01da-EP1b)
2023/06/14(水) 14:26:34.51ID:HNZbb8Sq0 >>189
その場合はメモリアクセス領域が変わるのでswapする前に取得済みだったイテレータは再取得する必要あり
その場合はメモリアクセス領域が変わるのでswapする前に取得済みだったイテレータは再取得する必要あり
193デフォルトの名無しさん (ワッチョイ e95f-2rqm)
2023/06/14(水) 15:52:59.34ID:K9MvWtl90 >186 が何を言ってるのか意味不明でこわい。
194デフォルトの名無しさん (ワッチョイ e95f-2rqm)
2023/06/14(水) 15:54:13.97ID:K9MvWtl90 >>191
「reset() すれば確保していた分のメモリを捨てられる」で間違いないでしょ。
「reset() すれば確保していた分のメモリを捨てられる」で間違いないでしょ。
195デフォルトの名無しさん (テテンテンテン MMeb-jufV)
2023/06/14(水) 18:26:24.05ID:9LyNOs9uM196デフォルトの名無しさん (ワッチョイ 219b-q0yD)
2023/06/14(水) 18:51:34.14ID:0kIiqVrM0 >>195
コンテナクラスがよろしくやってくれるのに任せるのであれば、スマートポインタで持たずに単にコンテナとして持つのと変わらないように思うのですが、違うのでしょうか。
ちゃんと理解していなかったら申し訳ありません。
コンテナクラスがよろしくやってくれるのに任せるのであれば、スマートポインタで持たずに単にコンテナとして持つのと変わらないように思うのですが、違うのでしょうか。
ちゃんと理解していなかったら申し訳ありません。
197デフォルトの名無しさん (ワッチョイ d17c-sLM4)
2023/06/14(水) 18:58:01.98ID:vjajEcDc0 vectorを信頼するなら単にclear()してshrink_to_fit()すればいい
信用できないならスマポで持っといていらなくなったら手動でブチ消せばいい
それすら信用できないならイチから自分で作れ
お前がどれだけ心配消化による
信用できないならスマポで持っといていらなくなったら手動でブチ消せばいい
それすら信用できないならイチから自分で作れ
お前がどれだけ心配消化による
198デフォルトの名無しさん (テテンテンテン MMeb-jufV)
2023/06/14(水) 19:18:20.42ID:YeSwNDrrM199デフォルトの名無しさん (ワッチョイ 219b-q0yD)
2023/06/15(木) 03:20:48.20ID:J1cG0ikp0 >>198
そもそもvectorのスマートポインタ (あるいはより一般的にサイズが動的なクラスのスマートポインタ) を作り、そのvectorやクラスのサイズを変えたときって確保されてる領域のサイズも変わるんでしたっけ?
手動で変えなきゃいけないと思っていました
(また、vectorのポインタとvectorの先頭要素のポインタは意味が違うのでよりわけが分からなくなりました)
そもそもvectorのスマートポインタ (あるいはより一般的にサイズが動的なクラスのスマートポインタ) を作り、そのvectorやクラスのサイズを変えたときって確保されてる領域のサイズも変わるんでしたっけ?
手動で変えなきゃいけないと思っていました
(また、vectorのポインタとvectorの先頭要素のポインタは意味が違うのでよりわけが分からなくなりました)
200デフォルトの名無しさん (ワッチョイ d17c-sLM4)
2023/06/15(木) 06:50:20.05ID:usfnoco+0 std::vectorはshrink_to_fit()呼ばない限り勝手にcapacity縮めたりしないはずだけど
201デフォルトの名無しさん (ワッチョイ d19c-jufV)
2023/06/15(木) 08:48:34.83ID:hMmgKiSo0202デフォルトの名無しさん (ワッチョイ b96e-ofsu)
2023/06/15(木) 09:00:49.34ID:K4jCDX8M0 シビアな状況でC++が使えないやつがCならOKなはずはない
203デフォルトの名無しさん (アウアウウー Sadd-g1CP)
2023/06/15(木) 10:11:47.24ID:dLjlwX4ma204デフォルトの名無しさん (ワイーワ2 FF63-pDI4)
2023/06/15(木) 10:56:55.78ID:kyFBXozFF 他所スレで同じ様な流れが
>742
質問の仕方が悪いだけwww
欲しい情報を引き出すには一定以上の質問能力が必要
>743
質問の仕方が重要なのはその通りだけど
ここで問題にしてるのは自分が詳しくない領域では質問の仕方が悪かったかどうかも分からないってことでしょうよ
>744
>>742
質問のしかたさえ良ければ正確な情報が手に入ると思ってるのは素人だけだぞ?w
>742
質問の仕方が悪いだけwww
欲しい情報を引き出すには一定以上の質問能力が必要
>743
質問の仕方が重要なのはその通りだけど
ここで問題にしてるのは自分が詳しくない領域では質問の仕方が悪かったかどうかも分からないってことでしょうよ
>744
>>742
質問のしかたさえ良ければ正確な情報が手に入ると思ってるのは素人だけだぞ?w
205デフォルトの名無しさん (ワッチョイ 219b-q0yD)
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様
ご丁寧な回答をくださりどうもありがとうございました。
勉強になります。
いや、ポインタのサイズなんて全く気にしてない。
質問は、メモリの解放をコンテナに任せるならわざわざスマポで持つ意味ないよね? ってこと。
で、コンテナに任せるというのは元の質問(>>182)への回答に全くなってないよね? ってこと。
(その理由は>>184,200様の書いてくださってる通り)
つーかお前が何も分かってないのは>>195でreset()しなくて良いとかほざいてる時点でお察し。
>>203-204
笑
>>203は>>191で「reset()しなくても良い」とかほざいてて>>195と同レベ。
>>183-185,194,197,200様
ご丁寧な回答をくださりどうもありがとうございました。
勉強になります。
206デフォルトの名無しさん (テテンテンテン MMeb-jufV)
2023/06/15(木) 12:29:34.24ID:QcI//Xn+M >>205
コンテナのsmart ptrの扱いは調べた?
コンテナの要素とポインタの参照先の違いについて根本的な誤解がありそう。
vectorはまだ構築していないインスタンス用のメモリ領域を予約するけど、smart ptrはそんなことしないよ。
vector<smart ptr>もsmart ptr の予約はするけど、smart ptrの参照先インスタンスの予約はしない。
コンテナのsmart ptrの扱いは調べた?
コンテナの要素とポインタの参照先の違いについて根本的な誤解がありそう。
vectorはまだ構築していないインスタンス用のメモリ領域を予約するけど、smart ptrはそんなことしないよ。
vector<smart ptr>もsmart ptr の予約はするけど、smart ptrの参照先インスタンスの予約はしない。
207デフォルトの名無しさん (ワッチョイ 219b-q0yD)
2023/06/15(木) 13:15:56.80ID:J1cG0ikp0 >>206
だから、結局任意のコンテナ、クラスに対してスコープ内でメモリを解放する方法は?
new で生ポを持って delete するか、スマポを持って reset するかだろ?
> vectorはまだ構築していないインスタンス用のメモリ領域を予約するけど、smart ptrはそんなことしないよ。
そりゃそう。
ゆえに、メモリを間違いなくリリースしたいなら reset すればよいのですねと>>190で述べている。
それで終わりなのにお前と来たら reset は不要だの元のコンテナの挙動に任せるだの、論旨を全く理解してないとんでもレスばっかり。
> vector<smart ptr>も……
論外。
誰もスマポのvectorの話なんてしてねえ。
だから、結局任意のコンテナ、クラスに対してスコープ内でメモリを解放する方法は?
new で生ポを持って delete するか、スマポを持って reset するかだろ?
> vectorはまだ構築していないインスタンス用のメモリ領域を予約するけど、smart ptrはそんなことしないよ。
そりゃそう。
ゆえに、メモリを間違いなくリリースしたいなら reset すればよいのですねと>>190で述べている。
それで終わりなのにお前と来たら reset は不要だの元のコンテナの挙動に任せるだの、論旨を全く理解してないとんでもレスばっかり。
> vector<smart ptr>も……
論外。
誰もスマポのvectorの話なんてしてねえ。
208デフォルトの名無しさん (ワッチョイ 8bfb-Xx8j)
2023/06/15(木) 14:56:16.78ID:M9bt3STi0 186でも言ってるがstaticもしくはvirtualでデストラクタ使えよ
それがシンプルで高速で1行も無駄のない設計な
それがシンプルで高速で1行も無駄のない設計な
209デフォルトの名無しさん (ワッチョイ 01c9-6bUV)
2023/06/15(木) 15:01:28.21ID:B8g22vaD0 182の
>最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが
がコンストラクタで確保してデストラクタで消す話というのはわかってる上で
>他に、オブジェクトに割り当てられているメモリを手動で解放する方法があったら教えてください。
なんじゃないの?
そんなものは無いっていう答えもあるにはあるけどサ
>最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが
がコンストラクタで確保してデストラクタで消す話というのはわかってる上で
>他に、オブジェクトに割り当てられているメモリを手動で解放する方法があったら教えてください。
なんじゃないの?
そんなものは無いっていう答えもあるにはあるけどサ
210デフォルトの名無しさん (ワッチョイ 13f0-8sUu)
2023/06/15(木) 18:41:07.51ID:QIwD56Ju0 最近IPP触り始めたんですが全部飽和演算で面食らってます
Modulo関数は無いんですか?
Modulo関数は無いんですか?
211デフォルトの名無しさん (ワッチョイ fb8c-jufV)
2023/06/15(木) 21:00:11.51ID:W1C5TI4i0 >>207
ああ、ごめん。めっちゃデカイインスタンスのvectorじゃなくて、めっちゃデカイvectorね。
それなら実装依存だけど>184か、>192とか参照無効化の制限とかコピーコストとかあるけど>189。189はsmart ptrにしとけば実用上問題ないかね。vectorのイテレーターは保存するものじゃないし。
ああ、ごめん。めっちゃデカイインスタンスのvectorじゃなくて、めっちゃデカイvectorね。
それなら実装依存だけど>184か、>192とか参照無効化の制限とかコピーコストとかあるけど>189。189はsmart ptrにしとけば実用上問題ないかね。vectorのイテレーターは保存するものじゃないし。
212デフォルトの名無しさん (ワッチョイ c14e-8sUu)
2023/06/15(木) 21:28:08.23ID:3cvhbwG+0 実際の所、vectorならclear()→shrink_to_fit()でメモリが開放されないこってありうるの?
213デフォルトの名無しさん (ワッチョイ d17c-sLM4)
2023/06/15(木) 22:10:40.95ID:usfnoco+0 規格上はshrink_to_fit()にメモリ解放する義務はないし、実装定義で何やっても自由(capacityを増やすような真似だけは禁止)
shrink_to_fit()がなんにもしない実装でも一応規格準拠になる
そんな糞みたいな実装が実在するかは知らない
shrink_to_fit()がなんにもしない実装でも一応規格準拠になる
そんな糞みたいな実装が実在するかは知らない
214デフォルトの名無しさん (US 0H0b-q0yD)
2023/06/16(金) 02:13:28.00ID:PZdB0bgSH215はちみつ餃子 ◆8X2XSCHEME (ワッチョイ c13e-2rqm)
2023/06/16(金) 11:31:25.61ID:QEmhRLek0 >>212
基本的には効率的に実装されるものだと信じて良いと思うが
どういう実装が効率的であるかは実行環境の事情による。
たとえばメモリ管理がページ単位というのは普通のことだし
その場合にページ単位より細かく確保したり解放したりしても非効率になる。
常に何もしないというような実装はあまりないと思うけど
解放するほうが非効率だと考えられる状況では
shrink_to_fit を呼んでも解放しなかったり部分的にだけ解放する
ということはそれなりにあり得そうだと思うよ。
基本的には効率的に実装されるものだと信じて良いと思うが
どういう実装が効率的であるかは実行環境の事情による。
たとえばメモリ管理がページ単位というのは普通のことだし
その場合にページ単位より細かく確保したり解放したりしても非効率になる。
常に何もしないというような実装はあまりないと思うけど
解放するほうが非効率だと考えられる状況では
shrink_to_fit を呼んでも解放しなかったり部分的にだけ解放する
ということはそれなりにあり得そうだと思うよ。
216デフォルトの名無しさん (ワッチョイ 01c9-6bUV)
2023/06/16(金) 12:08:14.46ID:nWXjt7Za0 capacityと OS側からみた空きメモリはまた別かもしれんわけで
アロケーターがOSからじかに要求してる場合もあれば
OSへの要求回数を減らして内部でプールしてやりくりしてるのもあるし
制御したいレイヤーによっては全部自前でやるしかない という落ちにも
アロケーターがOSからじかに要求してる場合もあれば
OSへの要求回数を減らして内部でプールしてやりくりしてるのもあるし
制御したいレイヤーによっては全部自前でやるしかない という落ちにも
217デフォルトの名無しさん (ワッチョイ c14e-8sUu)
2023/06/16(金) 12:26:43.83ID:B2wRJ7jC0 >>215
まぁ、細かい単位のメモリだったら、実際に開放されているかどうかなんて、ほとんど動作に影響しないとも言えるしね
(未初期化変数の不具合が発覚しづらい、くらいか)
とりあえずshrink_to_fitを呼んでおいて、細かいことは気にしないのが一番かもしれないw
まぁ、細かい単位のメモリだったら、実際に開放されているかどうかなんて、ほとんど動作に影響しないとも言えるしね
(未初期化変数の不具合が発覚しづらい、くらいか)
とりあえずshrink_to_fitを呼んでおいて、細かいことは気にしないのが一番かもしれないw
218デフォルトの名無しさん (ワッチョイ 934f-q0yD)
2023/06/16(金) 12:46:08.57ID:H6XPX5qB0 「STLコンテナ以外にも」という文言が読めてない文盲さんたちがvectorの話ばっかしててワロ
219デフォルトの名無しさん (ワッチョイ d969-2rqm)
2023/06/16(金) 15:41:25.79ID:KX+TErXo0 「STLコンテナ以外にも」はSTLコンテナも含むということ
STLコンテナの話をしても何もおかしくない
STLコンテナの話をしても何もおかしくない
220デフォルトの名無しさん (アウアウウー Sadd-g1CP)
2023/06/16(金) 15:43:23.81ID:ly+Q1cW8a いつものことだが
ほんの最初の数レスで終わってるのに
どうでも良い脱線ほど盛り上がってgdgdレスでスレが延びる
ほんの最初の数レスで終わってるのに
どうでも良い脱線ほど盛り上がってgdgdレスでスレが延びる
221デフォルトの名無しさん (アウアウウー Sadd-Xx8j)
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だろ?)で大きいメモリ確保しようなんて思うな」って話なんだよな
>STL コンテナ以外にも、大きいメモリが割り当てられてるオブジェクトを使用後に破棄したいというケースがよくあります。
>最も簡単なやり方は関数とか局所的なスコープとして切り出すことかと思いますが
いやいやそもそも「関数とか局所的なスコープ(つまりautoだろ?stackだろ?)で大きいメモリ確保しようなんて思うな」って話なんだよな
223デフォルトの名無しさん (ワッチョイ e95f-2rqm)
2023/06/16(金) 16:09:01.10ID:qgM8i0iT0 ローカルなvectorを置けばヒープ確保されるので「つまりautoだろ?stackだろ?」は
また何か誤解してる人が来たなとしか。
また何か誤解してる人が来たなとしか。
224デフォルトの名無しさん (ワッチョイ 219b-q0yD)
2023/06/16(金) 16:49:22.15ID:ybGonaVE0 reset要らないとか言ってる奴らは結局何なん
225デフォルトの名無しさん (テテンテンテン MMeb-jufV)
2023/06/16(金) 19:32:47.80ID:yx9ngvFiM226デフォルトの名無しさん (ワッチョイ 92dc-gfWY)
2023/06/17(土) 08:56:51.34ID:3MnK6eEg0 >>223
「STLコンテナ以外にも」という文言が読めてない文盲さんたちがvectorの話ばっかしててωωω
「STLコンテナ以外にも」という文言が読めてない文盲さんたちがvectorの話ばっかしててωωω
227デフォルトの名無しさん (テテンテンテン MM96-Axrn)
2023/06/17(土) 10:36:04.78ID:koF9X0k9M >>226
「大きいメモリが割り当てられてるオブジェクトを使用後に破棄したい」なら
>185か>187。
>187はunique ptrの置き場所と解放タイミングによって解放の仕方が違って、自動変数にして関数やスコープから抜けるタイミングで解放するなら手動操作不要、vectorなどのヒープに置くとかスコープの終わり前に解放したいとかならreset()とかvectorの要素削除とかで手動解放。
いずれにしても、自動変数に巨大インスタンスを考え無しに置くのは悪手で、そのオブジェクトがスタックに巨大データを置かない(ヒープ等に置く)ことを確認してからにしたほうがいい。
「大きいメモリが割り当てられてるオブジェクトを使用後に破棄したい」なら
>185か>187。
>187はunique ptrの置き場所と解放タイミングによって解放の仕方が違って、自動変数にして関数やスコープから抜けるタイミングで解放するなら手動操作不要、vectorなどのヒープに置くとかスコープの終わり前に解放したいとかならreset()とかvectorの要素削除とかで手動解放。
いずれにしても、自動変数に巨大インスタンスを考え無しに置くのは悪手で、そのオブジェクトがスタックに巨大データを置かない(ヒープ等に置く)ことを確認してからにしたほうがいい。
228デフォルトの名無しさん (ワッチョイ 6128-l8k0)
2023/06/17(土) 15:30:36.02ID:S+64vkUJ0 >>216
vectorのcapacityはそのvectorが氏ぬかcapacity縮小アクションが生じない限りvector固有に占有されるから
capacity(のうちsize()を超える分)と OS側からみた空きメモリはまた別でケテーイ……
一方malloc()がOSからゲットしたメモリをOSに返さずにいるのはOS側からみた空きメモリではないにしろ
同一プロセス内の他のオブジェクトの構築に使えるのだから空きメモリのうち
これすらもOSに返したいということならこの流れの中で現状答えがでていないキモヌ
vectorのcapacityはそのvectorが氏ぬかcapacity縮小アクションが生じない限りvector固有に占有されるから
capacity(のうちsize()を超える分)と OS側からみた空きメモリはまた別でケテーイ……
一方malloc()がOSからゲットしたメモリをOSに返さずにいるのはOS側からみた空きメモリではないにしろ
同一プロセス内の他のオブジェクトの構築に使えるのだから空きメモリのうち
これすらもOSに返したいということならこの流れの中で現状答えがでていないキモヌ
229デフォルトの名無しさん (ワッチョイ 6128-l8k0)
2023/06/17(土) 15:31:34.82ID:S+64vkUJ0 まあしいて言えばプロセスを一旦exitして再立ち上げ?
230デフォルトの名無しさん (ワッチョイ 6128-l8k0)
2023/06/17(土) 15:45:09.56ID:S+64vkUJ0 普通に作ったら(コードで明示的に直接OSのAPIでメモリを分捕って解放とかしない限りは
プロセスのprivate bytesはプロセスが氏ぬまで増えることはあっても減ることは無いという印象、
プロセスのprivate bytesはプロセスが氏ぬまで増えることはあっても減ることは無いという印象、
231デフォルトの名無しさん (ワッチョイ 7d9b-trtU)
2023/06/17(土) 16:27:35.20ID:5e+acAEX0 >>225
スマンまじで理解できないのだけど、なぜvectorに限った話をしてるの?
スマンまじで理解できないのだけど、なぜvectorに限った話をしてるの?
232デフォルトの名無しさん (テテンテンテン MM96-Axrn)
2023/06/17(土) 19:22:00.09ID:mYwWSuEFM >>231
巨大インスタンスは>227
巨大インスタンスは>227
233デフォルトの名無しさん (ワッチョイ d9ab-trtU)
2023/06/17(土) 19:29:36.10ID:HtrmHz3i0234デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
2023/06/17(土) 19:54:50.95ID:9hSxsWrs0 アロケータ気に入らないなら自作くらいしろよポンコツ
なにもかもSTLに頼りやがってそれでPGやってるつもりになるなよ
なにもかもSTLに頼りやがってそれでPGやってるつもりになるなよ
235デフォルトの名無しさん (ワッチョイ 6128-l8k0)
2023/06/17(土) 20:19:47.36ID:S+64vkUJ0 人類には早すぎた話題また……
236デフォルトの名無しさん (オイコラミネオ MM91-L1I+)
2023/06/17(土) 23:14:07.63ID:H9lc23A5M 次世代の人は便利に使いこなしてるかより簡素になった仕組みを使うのだろう
237デフォルトの名無しさん (ワッチョイ 655f-rdTE)
2023/06/18(日) 03:00:55.26ID:GIMFAM+a0 >>231
コンテナの種類を問わない一般的な方法なんてものはないからじゃないですかね
コンテナの種類を問わない一般的な方法なんてものはないからじゃないですかね
238デフォルトの名無しさん (ワッチョイ 8101-1tDD)
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;
}
何故か分かります?
#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;
}
239デフォルトの名無しさん (ワッチョイ 515f-C6j3)
2023/06/18(日) 21:45:44.90ID:UCXMUPHB0 >>238 エラーメッセージ見ればたぶん分かる。
240デフォルトの名無しさん (ワッチョイ 8101-1tDD)
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;
レス有難うございます
まず訂正
-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;
241デフォルトの名無しさん (ワッチョイ 9e81-L1I+)
2023/06/18(日) 23:15:51.41ID:w3/xAOT+0 ADLでoperator+が見つからないからかな?
struct Vector : std::array <double, 3> {};
みたいに定義したらいけるのでは
struct Vector : std::array <double, 3> {};
みたいに定義したらいけるのでは
242デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/18(日) 23:20:13.62ID:VwYqKwPk0243デフォルトの名無しさん (ワッチョイ 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名前空間に入れてやれば動くにゃ動くけど色々マズいので(調査する分にはいいけど)最終的な解答にはならないかな
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名前空間しか検索しないんだと思う
たぶんC++コンパイラはoperator+の候補を検索するときに
Vector( = std::array<double, 3>)と同じ名前空間にあるものしか検索しない
Vectorのクラス定義そのものがグローバル名前空間にあるなら14行目のoperator+を見つけられるけど、
今はVectorの正体はstd::array<...>なのでstd名前空間しか検索しないんだと思う
245デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/18(日) 23:39:19.50ID:VwYqKwPk0246デフォルトの名無しさん (ワッチョイ a901-UvLK)
2023/06/18(日) 23:48:03.44ID:EGGkT3O00 独自のメンバ変数を持たないのなら継承してしまうのも手ではある(ただしコンストラクタやarrayを受け取るキャスト用コンストラクタとか書く必要が出ると思うけど)
ただ、そもそもカスタマイズしたり自分の用途に本当に使いやすいものを作りたいなら、ちゃんと自分で全部書いた方がいいと思うよ
ただ、そもそもカスタマイズしたり自分の用途に本当に使いやすいものを作りたいなら、ちゃんと自分で全部書いた方がいいと思うよ
247デフォルトの名無しさん (ワッチョイ b110-lSMs)
2023/06/19(月) 00:42:02.49ID:2lgIrH6A0 >>245
std::accumlateの定義内からだと、その下の方(ユーザーコード)で定義されてるoperator+は見えてないので、グローバル名前空間の探索では見つからない
std::accumlateの定義内からだと、その下の方(ユーザーコード)で定義されてるoperator+は見えてないので、グローバル名前空間の探索では見つからない
248デフォルトの名無しさん (ワッチョイ 8101-1tDD)
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>
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で対象外なのが問題
言われてる通りADLで対象外なのが問題
250デフォルトの名無しさん (ワッチョイ 256b-trtU)
2023/06/19(月) 05:38:23.58ID:JAsvvATP0 >>237
(スマート)ポインタで持って要らなくなったら明示的にリリースする方法はあらゆるコンテナに対して使えるよね?笑
(スマート)ポインタで持って要らなくなったら明示的にリリースする方法はあらゆるコンテナに対して使えるよね?笑
251デフォルトの名無しさん (ワッチョイ f59c-Axrn)
2023/06/19(月) 08:48:03.43ID:KLBRX38t0252デフォルトの名無しさん (ワッチョイ 8101-1tDD)
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クラスに対する演算子だから通る)
外部の演算子見に行くのは目的に合わんのじゃね
std名前空間内のarrayに外部から勝手に動作を追加しようとしてるんだから、あまりよろしくないやり方しようとしてると考えた方がいい
(だから>>246のように書いた、継承したら一応arrayではなくちゃんとVectorクラスに対する演算子だから通る)
254デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/19(月) 11:53:54.08ID:Q4g6N6uX0255デフォルトの名無しさん (ワッチョイ 5efb-+wmN)
2023/06/19(月) 12:20:34.90ID:4PINPeBN0 つまりvector<int>を使いなさいということ
256デフォルトの名無しさん (ワッチョイ 7d9b-trtU)
2023/06/19(月) 12:21:25.69ID:wGtx/iKL0 >>251
安価ミス
安価ミス
257デフォルトの名無しさん (アウアウウー Sacd-9XmN)
2023/06/20(火) 00:04:57.81ID:YSi65ASja 実引数依存の名前探索、Argument-Dependent Lookup (ADL)は、
Koenig lookup とも言う
「Cプログラミングの落とし穴」の著者、
Koenigが、C++ に入れる事を推奨した
ADLを知っているなら、かなりのプロと言える
Koenig lookup とも言う
「Cプログラミングの落とし穴」の著者、
Koenigが、C++ に入れる事を推奨した
ADLを知っているなら、かなりのプロと言える
258デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 00:18:46.72ID:vGfe0Eju0 勉強になります
259デフォルトの名無しさん (アウアウウー Sacd-9XmN)
2023/06/20(火) 02:12:24.83ID:1vctBLGTa 演算子のオーバーロードなら、フレンド関数とか?
非メンバの演算子オーバーロード | Programming Place Plus C++編【言語解説】 第35章
https://programming-place.net/ppp/contents/cpp/language/035.html
非メンバの演算子オーバーロード | Programming Place Plus C++編【言語解説】 第35章
https://programming-place.net/ppp/contents/cpp/language/035.html
260はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/20(火) 10:05:39.77ID:IIzrqfbq0 状況を簡略化するとこう。
namespace ns {
struct foo {};
template <class T>
void bar(const T&) {
T() + T();
} };
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
int main() { bar(ns::foo()); }
ADL は「通常の探索に加えて」関連する名前空間も探索対象にするルールなのでグローバル名前空間も探索対象になるが、通常の探索では後ろで宣言 (定義) されているものは見つけることができない。 この場合はエラーとして検出されるけど、可視な宣言と実際の定義の集合に食い違いは未定義という解釈でいいと思う。 (ちょっと自信はない……。)
だから順序を変えれば通る。
namespace ns {
struct foo{};
};
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
namespace ns {
template <class T>
void bar(const T&) {
T() + T();
} };
int main() { bar(ns::foo()); }
当然ながら std の (というかそれに限らず既存のライブラリの) 宣言の順序をどうこうするわけにもいかないので無理にカスタムしようとするのは筋が悪いということになる。
namespace ns {
struct foo {};
template <class T>
void bar(const T&) {
T() + T();
} };
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
int main() { bar(ns::foo()); }
ADL は「通常の探索に加えて」関連する名前空間も探索対象にするルールなのでグローバル名前空間も探索対象になるが、通常の探索では後ろで宣言 (定義) されているものは見つけることができない。 この場合はエラーとして検出されるけど、可視な宣言と実際の定義の集合に食い違いは未定義という解釈でいいと思う。 (ちょっと自信はない……。)
だから順序を変えれば通る。
namespace ns {
struct foo{};
};
ns::foo operator+(const ns::foo& x, const ns::foo& y) { return ns::foo(); }
namespace ns {
template <class T>
void bar(const T&) {
T() + T();
} };
int main() { bar(ns::foo()); }
当然ながら std の (というかそれに限らず既存のライブラリの) 宣言の順序をどうこうするわけにもいかないので無理にカスタムしようとするのは筋が悪いということになる。
261デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 10:53:08.18ID:vGfe0Eju0 >>260
>だから順序を変えれば通る。
最近手元のg++を更新しまして10.2.1 -> 12.2.0になったんですが
前者のケースが通らなくなりまして疑問に思っていたところでした
10.2.1は寛容で両方とも通るけどC++的には後者のみ通るのが正しい?
>だから順序を変えれば通る。
最近手元のg++を更新しまして10.2.1 -> 12.2.0になったんですが
前者のケースが通らなくなりまして疑問に思っていたところでした
10.2.1は寛容で両方とも通るけどC++的には後者のみ通るのが正しい?
262はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/20(火) 11:41:30.21ID:IIzrqfbq0 >>261
前者はたぶん未定義かつ診断不要な状況なのでエラーを検出せずに通すのも正しい挙動で
プログラマがそういう状況を作ってしまうのが仕様に反する (というか結果が保証されない) という解釈になると思う。
前者はたぶん未定義かつ診断不要な状況なのでエラーを検出せずに通すのも正しい挙動で
プログラマがそういう状況を作ってしまうのが仕様に反する (というか結果が保証されない) という解釈になると思う。
263デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 13:36:04.44ID:vGfe0Eju0 なるほどー
有難うございます
有難うございます
264デフォルトの名無しさん (JP 0H91-FhUT)
2023/06/20(火) 21:39:35.82ID:Pk8V/jejH template<typename Callback>
void func(Callback cb)
{
//cb(1); // A
//cb(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
AとBをコンパイル時に呼び分けたいんですけど
どのように記述すればよいか教えていただけませんか?
void func(Callback cb)
{
//cb(1); // A
//cb(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
AとBをコンパイル時に呼び分けたいんですけど
どのように記述すればよいか教えていただけませんか?
265デフォルトの名無しさん (ワッチョイ 515f-9XmN)
2023/06/20(火) 22:18:37.18ID:Cuq1USIJ0 is_invocableでおk
266はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/20(火) 22:21:49.81ID:IIzrqfbq0 >>264
渡されたコールバック関数の引数の数によって区別するってこと?
素朴な方法だとオーバーロードするのが手っ取り早いと思う。
void func(void (*cb)(int)) {
cb(1);
}
void func(void (*cb)(int, int)) {
cb(1, 2);
}
void f1(int) {}
void f2(int, int) {}
int main() {
func(f1);
func(f2);
}
渡されたコールバック関数の引数の数によって区別するってこと?
素朴な方法だとオーバーロードするのが手っ取り早いと思う。
void func(void (*cb)(int)) {
cb(1);
}
void func(void (*cb)(int, int)) {
cb(1, 2);
}
void f1(int) {}
void f2(int, int) {}
int main() {
func(f1);
func(f2);
}
267デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 22:27:55.14ID:vGfe0Eju0 >>264
template<typename Callback> void func(Callback cb);
template <> void func(void (*cb) (int))
{
(*cb)(1); // A
}
template <> void func(void (*cb) (int, int))
{
(*cb)(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
template<typename Callback> void func(Callback cb);
template <> void func(void (*cb) (int))
{
(*cb)(1); // A
}
template <> void func(void (*cb) (int, int))
{
(*cb)(1,2);// B
}
void f1(int){}
void f2(int,int){}
int main(){func(f1);}
268デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 22:29:12.98ID:vGfe0Eju0 templateが意味ないね
269デフォルトの名無しさん (ワッチョイ 127f-L1I+)
2023/06/20(火) 22:39:00.27ID:ui/rWsWf0 265が言うようにis_invocable使うとこんな感じ?
template<typename Callback>
void func(Callback cb)
{
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
}
template<typename Callback>
void func(Callback cb)
{
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
}
270デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 22:41:37.75ID:vGfe0Eju0 >>269
これって関係ないif節はコンパイル時に消えるの?
これって関係ないif節はコンパイル時に消えるの?
272デフォルトの名無しさん (JP 0H91-FhUT)
2023/06/20(火) 22:44:14.18ID:Pk8V/jejH273デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/20(火) 22:47:27.45ID:vGfe0Eju0274デフォルトの名無しさん (JP 0H91-FhUT)
2023/06/20(火) 22:48:18.64ID:Pk8V/jejH >>269
まさにこれをやりたかったです。
template<typename Callback>
void func(Callback cb)
{
// こことか
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
// ここをどうしようか悩んでいました
}
まさにこれをやりたかったです。
template<typename Callback>
void func(Callback cb)
{
// こことか
if constexpr (std::is_invocable_v<Callback, int>) {
cb(1);
} else if constexpr (std::is_invocable_v<Callback, int, int>) {
cb(1,2);
}
// ここをどうしようか悩んでいました
}
275はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/20(火) 22:59:00.24ID:IIzrqfbq0276デフォルトの名無しさん (JP 0H91-FhUT)
2023/06/20(火) 23:14:31.48ID:Pk8V/jejH277デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
2023/06/20(火) 23:42:05.71ID:zCL4VLm70 >>273
ザッツcostexprマジック
ザッツcostexprマジック
278デフォルトの名無しさん (ワッチョイ 69f0-J7ro)
2023/06/20(火) 23:43:57.61ID:zCL4VLm70 n抜けてたwコストがかかる演算なのは確かだけどw
constexprマジック!マジック!
constexprマジック!マジック!
279デフォルトの名無しさん (ワッチョイ 32fb-dYQK)
2023/06/21(水) 00:07:10.76ID:2lh42auf0 C++11のSFIANE地獄へようこそ
https://wandbox.org/permlink/2sfUVeEBrErqvI2R
template関数の実体化が1つだけ成功して、
他が失敗するように仕掛ければ呼び分けは可能。
ただ見ての通り相当面倒なことを書かなきゃならない。
https://wandbox.org/permlink/2sfUVeEBrErqvI2R
template関数の実体化が1つだけ成功して、
他が失敗するように仕掛ければ呼び分けは可能。
ただ見ての通り相当面倒なことを書かなきゃならない。
280デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/21(水) 00:28:02.40ID:CWKUsltc0281はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 0d3e-C6j3)
2023/06/21(水) 00:41:42.51ID:3HBFHOpK0282デフォルトの名無しさん (ワッチョイ 515f-9XmN)
2023/06/21(水) 00:42:09.27ID:LxMKpynY0 templateでやるのは質問者の与えた要件だな
宿題なんじゃね、しらんけど
宿題なんじゃね、しらんけど
283デフォルトの名無しさん (ワッチョイ 32fb-9xvA)
2023/06/21(水) 00:52:13.25ID:2lh42auf0 C++14にはif constexprが存在しないから
template使ったオーバーロードしか手段がない
質問者がC++14環境でって言ってたからこんなクソ面倒くさいことやれば一応できるっていう例示
template使ったオーバーロードしか手段がない
質問者がC++14環境でって言ってたからこんなクソ面倒くさいことやれば一応できるっていう例示
284デフォルトの名無しさん (ワッチョイ 8101-1tDD)
2023/06/21(水) 01:17:47.52ID:CWKUsltc0 >>281,283
ありがとう
>引数として int を渡せる (int から暗黙に変換可能な仮引数を持っている) というのと
>厳密に int そのものでなければならないというのとでは制約の厳しさが違う。
こういうことね
ありがとう
>引数として int を渡せる (int から暗黙に変換可能な仮引数を持っている) というのと
>厳密に int そのものでなければならないというのとでは制約の厳しさが違う。
こういうことね
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 橋下徹氏 外務省幹部の訪中受け「口だけ番長」へ痛烈指摘 「喧嘩は日本の完敗…なんとかっこ悪い日本か」 [冬月記者★]
- 習政権、高市首相への態度硬化 台湾有事発言で連日非難 中国 ★11 [ぐれ★]
- 【外国人問題】小野田紀美担当相「不法就労や不法滞在は許さない」 [シャチ★]
- 【野球】井端監督 大谷翔平、山本由伸らのWBCへの参加 「1日も早く返事ほしい」「待っててといっても、国内組が遅くなってしまう」★3 [冬月記者★]
- 経団連会長、日中は建設的対話を 経済3団体が高市首相と初会談も日中関係は話題に登らず… [BFU★]
- 東京株式市場 インバウンド関連株が下落 中国政府の渡航自粛要請で [バイト歴50年★]
- 橋下徹「口だけ番長の日本が中国に喧嘩負け。なんとカッコ悪い日本か!」高市にバチーン!✴ [153490809]
- 【高市早苗】習近平激怒か [115996789]
- 中国「高市が頭を下げて謝罪しない限り、絶対に許さない」 [329329848]
- 🏡
- ワンピースの評価ガタ落ちしてるけど尾田っちのメンタルが心配
- ガンダム←名言ばかり エバー(笑)←こいつ(笑)
