1 名前:デフォルトの名無しさん mailto:sage [2008/08/26(火) 12:01:17 ] C++標準ライブラリの一つ、STLについて。 前スレ 【C++】STL(Standard Template Library)相談室 9 pc11.2ch.net/test/read.cgi/tech/1204045410/ 過去ログ・リンク・書籍紹介は >>2 以降
474 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 22:12:15 ] vectorならreserveは必須だと思う dequeってどうだろう
475 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 22:21:59 ] dequeはある一定の長さのブロックが不連続に確保されるそうだから reserveしたらシステムからメモリを持ってくる時間は稼げるけどvector と違ってメモリの再配置は起きにくいんだよね
476 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 23:24:27 ] それは実装によるんでは。
477 名前:デフォルトの名無しさん mailto:sage [2008/11/12(水) 23:32:37 ] 実装によるのはもちろんだが一般的な実装の話ね
478 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 01:13:27 ] dequeのpush_backが(償却じゃなくて正真正銘の)定数時間であることは規格で要求されてたはず だから一概に実装に依るとも言えない
479 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 07:48:57 ] dequeはpush_back/push_frontで既存要素のコピーが起こりえないのがありがたい まあ最初から要素数が判ってるならvector一択だけど
480 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 20:37:08 ] STLのことは良く分からないけど、 list,stack,queue,vector,dequeで空のクラスSampleのポインタを、 10万個格納、(1個delete&削除・1個格納)*10万回、 空になるまでdelete&要素削除 してみた。 vectorは予め追加要素の2倍reserve()した。 要素の追加削除はvector,stack以外『古い物から削除』、前から取り出して後ろから追加でやった。 stack、queueはそれぞれコンテナdequeを利用。 list 68.11 秒 vector 20.344 秒 stack 27.5 秒 deque 9.468 秒 queue 9.438 秒 queueが速すぎてワロタ dequeは操作する方向次第でstackとほぼ同等 queue,stack,dequeはこの場合、実質同じモノだし queue,stackのコンテナを変えたら悲惨な結果になった PCが悲鳴を上げたのでこれ以上のテスト回数は勘弁
481 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 20:41:18 ] あぁ、次はboost::circular_bufferだ…
482 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 20:58:12 ] >481 >480と同条件、上限20万個として計測してみた。 平均5.5秒くらいだった
483 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 23:21:57 ] ひょっとしてlistってあんまり使わない方が良い?
484 名前:デフォルトの名無しさん mailto:sage [2008/11/13(木) 23:51:07 ] むしろ連結リストのくせに良い数字が出てると思うがね
485 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 00:18:06 ] リンクリストより配列のほうがキャッシュに引っかかりやすいからいいぞってMSも言いている。 msdn.microsoft.com/ja-jp/library/eye126ky.aspx
486 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 00:33:54 ] >>483 状況次第 listのほうが向いてる使い方もあるしね
487 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 00:54:30 ] 途中(先頭末尾以外)の要素の削除はlistじゃないとやってられんやろー
488 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 00:55:31 ] あとリストの連結やリストの分割もあるか あれ?そんなことできたっけ・・・?
489 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 01:01:03 ] とりあえずただデータを突っ込んで置きたい(出し入れ順番とかどうでも良い)場合には、 リストは不向きってことか
490 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 01:14:52 ] 昔はやたらとリンクリストを使うのがいいとされていたが、 今のご時世でも初心者にリンクリストを教えたがる間抜けが後を絶たない。 普通にstd::vectorを使えるように仕込んでおけば、std::listを使うのも苦労はないだろうに。
491 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 01:15:39 ] >>487 途中の削除もdequeは結構速い。 listは削除してもイテレータが無効にならないのが利点かな。
492 名前:1/2 mailto:sage [2008/11/14(金) 15:46:52 ] listを使っていてよく分からない事態に遭遇したので質問します。 長くなってしまったので申し訳ありませんが分割投稿します。 環境:VC++2005 / XP typedef struct globalArray { int type; char name[100]; float variable[5][5]; } globalVar; typedef struct nodeDat { CShaderNode *nodeKind; globalVar varDat[5]; // 上の構造体(globalVar) int dataNum; float power; } nodeData; typedef struct _data { nodeData mainNode; // 上の構造体(nodeData) nodeData blendNode; // 上の構造体(nodeData) nodeData subNode; // 上の構造体(nodeData) int materialNum; dxMaterial *matrials[MAX_MATNUMBER]; } dataBlock;
493 名前:2/2 mailto:sage [2008/11/14(金) 15:47:25 ] 上のような構造体が有りまして、一番下のdataBlockをリストとして扱っているのですが、 dataBlock tmp; /* 〜 データ作成処理 〜 */ /* 〜 挿入先探索 〜 */ insert(itr,tmp); とデータを挿入してリストを覗くと途中までしか正しくデータが入っていません。 データ作成過程で"",NULL,0.0fと全て初期値を用いてデータを初期化しているのですが、 data[0]->mainNode.varDat[0].variable 以降のデータが未初期化のまま生成されています。 構造体を入れ子にする前は正しく動いていたのですが、 listを扱う際は構造体を入れ子で扱うとNG等の制約があるのでしょうか。 ご教授お願いいたします。
494 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 15:53:19 ] それだけだと推測しかできん ・初期化の部分が不完全か ・未初期化というのが勘違いか ・リスト操作がバグってるか のいずれかしかないが、心当たりがないなら何か見逃してるんだろう そのようなNG的制約は無いので大丈夫
495 名前:492 mailto:sage [2008/11/14(金) 16:04:13 ] 返信ありがとう御座います。 (※(int)はキャストではなく型を説明上明示するために便宜的につけた物です。紛らわしくてすみません。) 例えば仮データ(tmp)で、 (int)materialNumを0で初期化したのがリストのデータでは (int)materialNumが-33686019になってしまっているので、 >・リスト操作がバグってる のでしょうかね…… ありがとうございます。制約は無いときいて安心しました。 もう少し追ってみます。
496 名前:492 mailto:sage [2008/11/14(金) 16:30:43 ] 連投失礼いたします。 色々弄ってみたところ、構造体のメンバの記述順を入れ替えると正確に入るデータと入らないデータが出てきました。 詳しく調べたところ、連結しようとしている構造体は180byteで、リストで正しく入るのは96byteの領域まででした。 数字的にこれって多分仕様ですよねぇ……
497 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 18:55:54 ] -33686019ってことは0xfdだろ? ちゃんとdeep-copyせんと。
498 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 19:59:55 ] dataBlock tmpA; /* 〜 データ作成処理 〜 */ dataBlock tmpB; tmpB = tmpA; ってやって、tmpAとtmpBは同じ内容の独立したオブジェクトになる?
499 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 20:04:28 ] 誰にもわかりません
500 名前:492 mailto:sage [2008/11/14(金) 21:01:27 ] 返信ありがとう御座います。 >>498 さんのを実行してみたところ、同内容の独立したオブジェクトに成りました。 deep-copyなのですが、 /* 〜データ作成処理〜 */ を抜けた後、tmpに全ての値がきちんと入っていることを確認し、 data.insert(itr,tmp); でインサートを行っているのですがコピーに関してはlist側で処理されている様で、 こちら側からコピー処理を定義することが出来るのでしょうか。
501 名前:デフォルトの名無しさん mailto:sage [2008/11/14(金) 21:50:22 ] >>500 コピー演算子をオーバーロード。
502 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 00:35:09 ] その場合はコピーコンストラクタじゃ?
503 名前:492 mailto:sage [2008/11/15(土) 01:20:38 ] すみません、何かもう全く関係ないところが原因っぽいです。 構造体のメモリ領域と他のクラスのメモリ領域が被ってる……
504 名前:デフォルトの名無しさん [2008/11/15(土) 03:13:32 ] あるIDを割り当てるクラスを作成しようと思っています インターフェースとしてはこんなかんじで class IDAllocator{ uint32_t T AllocID(); void FreeID(uint32_t id); }; クライアントコードに対して、一意なIDを割り当てるのですが、 IDを使い終わった後は返却し、後ほど再利用できる様にしたいです。 IDを割り当てる際に、現在使われてないIDの内、最小の数値のIDを返す仕様にしたいのですが、 STL的にかっちょいい実装方法を教えてください 今のところ割り当て済みのIDをvectorに記録しておいて、0から1ずつ増やしてvectorに無いIDがあれば それを使うというどう考えても効率の悪いやり方でやっています
505 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 03:44:37 ] 使い終わって返却されたIDをpriority_queueに記録し、再利用するときはそこから取り出す
506 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 03:48:12 ] priority_queueが空なら新たに生成する→新しいIDは最も大きい数値になる ってことか
507 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 09:29:56 ] インテレータの有効性をチェックする方法はない? 何も代入されてないときなど、別の変数でフラグ保持するのは面倒だと思うので
508 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 09:59:37 ] とりあえずend()でも入れとけとか、 有効/無効状態をチェックするなとか、 そもそもインテレータって何とか。
509 名前:デフォルトの名無しさん mailto:sage [2008/11/15(土) 14:38:28 ] そんなあなたにboost::optional
510 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 01:05:27 ] >488 splice 使えばできるはず。
511 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 01:53:37 ] これっておかしくない? ttp://www.geocities.jp/ky_webid/cpp/library/008.html
512 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 01:57:21 ] >>511 どこがどうおかしいと思うのか書けやカス
513 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 11:21:20 ] とりあえずテンプレートクラスはクラステンプレート
514 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 12:11:13 ] enumの値か?
515 名前:デフォルトの名無しさん [2008/11/16(日) 12:14:51 ] それは別に間違ってなくね
516 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 12:16:41 ] MIRROR_X
517 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 12:24:52 ] 問題ないだろ MIRROR_X = SCALE | ROTATE を意図して書いてあるならな。
518 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 12:35:10 ] はー?
519 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 12:50:45 ] enum bitset 二大不要物(笑)
520 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 12:54:39 ] enumを不要とか言うやつは素人
521 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:04:54 ] enum要らないとか言う奴はただのバカかTMPしない人だろ
522 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:08:23 ] >C言語であれば、ANDやOR等の演算を使って管理しますが、C++ではbitsetが利用できます。 この辺りで馬鹿を晒している。このサイトも勿論、私のダメサイトリストに載っている。
523 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:10:34 ] じゃぁbitsetってなんに使うの?
524 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:13:37 ] ビット単位のフラグの管理をせざるを得ないときに使うかなぁ。ま、そのときが来たら考えるよ。
525 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:16:23 ] >>522 上級者のあなたがおすすめするサイトを教えてください
526 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:20:55 ] >>523 >>519
527 名前:522 mailto:sage [2008/11/16(日) 13:23:15 ] 残念ながら今のところ、初心者に安心してお勧めでキルサイトは見つけていない。 したがって、申し訳ないが期待には応えられない。 ちなみに、私のダメサイトリストは正しくは、「初心者にはお勧めできない(≒ダメ)サイトリスト」だ。 中級者辺りが読む分には、(自力で確認できるノウハウもあるだろうから)まぁ、悪くないかもしれない。
528 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:34:14 ] enumは型安全じゃないのが気に要らないな
529 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:35:07 ] C++のenumは、|=するだけでキャストが必要な糞仕様
530 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:44:26 ] 俺は#define派 enumだとアセンブラソースから使えないから
531 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 13:54:37 ] >>529 そもそもビットフラグで使うとは限らないわけで…
532 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 14:08:21 ] >>519 unionに失礼だろw
533 名前:デフォルトの名無しさん mailto:sage [2008/11/16(日) 16:05:41 ] それは128ビットとかに使うぞ
534 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 09:37:02 ] お前らみんな、unionさんに謝れ!
535 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 15:37:45 ] アマチュアの俺からすると分からんのだけど、unionって実際の業務で使われてるの? enumなんかは割りと使ってるんだけど
536 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 15:48:34 ] >>535 使うこともあるよ。Cでbitsetもどきを実装するときとか。
537 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 17:54:37 ] 大きな数値から上位ビットと下位ビット分けたり
538 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 18:04:00 ] ・建前 unionは環境に激しく依存するから、使わない方がいい。 ・本音 いまどきビッグエンディアンとか無いだろw
539 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 18:11:15 ] オレも、エンディアン、ビット幅、signedの右シフト、除算の符号は実装決めうちで作ってる
540 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 18:14:14 ] >>538 サーバ系では未だにSunが頑張っているから無視できないのよね。
541 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 18:33:05 ] うにおんは組み込みCで以前使ってた事がある おそらく今でも使ってる
542 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 18:45:55 ] 1の補数はもう絶滅でいいだろ
543 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 18:50:13 ] 引き算どうすんだよw
544 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 18:59:06 ] 負数の表現方法のことだろ。
545 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 19:17:14 ] それは2の補数
546 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 19:19:57 ] ja.wikipedia.org/wiki/%E7%AC%A6%E5%8F%B7%E4%BB%98%E6%95%B0%E5%80%A4%E8%A1%A8%E7%8F%BE
547 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 22:16:38 ] よその言語だとASCIIにIEEE754も決め打ちと化しているものもあるよな。
548 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 23:10:13 ] 未だにIBMのサーバでEBCDICとかあるから油断できない
549 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 23:51:08 ] >>538 俺はエンディアン入れ替えたいからunion使ってる。 union { double a; char b[8]; }
550 名前:デフォルトの名無しさん mailto:sage [2008/11/17(月) 23:54:30 ] つーかネットワークバイトオーダはbigだし 画像処理でもエンディアン入れ替えなんてよくやるでしょ 全部littleで済むと思ってる人ってどういう世界に生きてるんだ?
551 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 00:08:27 ] 意識する場面なんてほとんどないな
552 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 00:11:46 ] >>550 そういうときに、必ずエンディアン変換を挟むコードを書いてしまう(あるいは書かない) というのがエンディアン決め打ちのコーディングだと思う。
553 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 00:14:19 ] #ifdefるだろjk
554 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 00:41:30 ] いや、自動判断する。 例えばtiffはヘッダのIかMかで判断できるし、実行環境がどっちなのかはint foo = 0とでもして& fooをchar *にキャストして取り出せば判る。
555 名前:554 mailto:sage [2008/11/18(火) 00:51:28 ] s/int foo = 0/int foo = 1/ まぁ、unionは使わないけれど。
556 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 00:53:15 ] スレから脱線するが、標準の方法でエンディアンをコンパイル時に知る方法ってある? 実行時ならできるんだが
557 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 00:58:32 ] boost/detail/endian.hppとかを見る限り、標準では無さそうだね
558 名前:デフォルトの名無しさん mailto:わざとだが sage [2008/11/18(火) 01:50:26 ] >>556 コンパイル環境のエンディアンを? それとも、ターゲット環境?
559 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 01:58:09 ] >>556 VxWorksなら_BYTE_ORDERのdefine見れば分かるが他はしらん。
560 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 13:28:05 ] >>554 PDP-11位だしな変態なの
561 名前:デフォルトの名無しさん mailto:sage [2008/11/18(火) 14:44:19 ] >>560 お前はSun、IBM、MIPSを敵に回した。
562 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 16:25:22 ] vectorについてですが array.reserve(array.size()); でぴったりのサイズに変わるかと思ったのですが変わりません。 大きなデータを扱ったりする場合、ぴったりのサイズで作り直した方が メモリが節約できるかと思うのですが、なぜうまくいかないのでしょうか。 何かいい方法はないでしょうか?
563 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 16:28:10 ] vector<T>(array).swap(array);
564 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 16:32:01 ] reserveは拡大する方向にしか働かないのでは
565 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 16:36:13 ] >>>562 §23.2.4.2.2 void reserve(size_type n); 2 Effects: A directive that informs a vector of a planned change in size, so that it can manage the storage allocation accordingly. After reserve(), capacity() is greater or equal to the argument of reserve if reallocation happens; and equal to the previous value of capacity() otherwise. Reallocation happens at this point if and only if the current capacity is less than the argument of reserve(). 3 Complexity: It does not change the size of the sequence and takes at most linear time in the size of the sequence. greater or qrual と書いてあるから等しいかもしくは大きいとなるので ぴったりのsize()になる保証はない。
566 名前:デフォルトの名無しさん mailto:sage [2008/11/19(水) 16:37:52 ] おっと equal to the previous value of capacity() otherwise. ともあるから、縮小しようとしてもcapacity()は変化しない事になる。 詰まるところ>>563 のようにスワップ技法に頼るしかない。
567 名前:562 mailto:sage [2008/11/20(木) 11:20:10 ] >>563-566 出来ました。ありがとうございます。 サイズの縮小は出来ないんですね。勉強になりました
568 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 01:13:58 ] 今までイテレータが指してるコンテナのことをイテランドと呼んでたんですが そんなの聞いたことないって言われました ぐぐってもほとんど出てこないので不安になってきたんですが(「イテランド」だとゼロ…) 普通に使いますよね?
569 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 01:17:07 ] はつみみです
570 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 01:18:50 ] ぐぐった時点で気づいてるだろwwww俺は聞いたこと無いな iterandにしたら多少出てくるけど、まぁスズメの涙ね
571 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 01:24:17 ] あーやっぱり? iterandは1000件くらい引っかかるから、わざわざカタカナにしないだけで あっちでは普通の言葉かもしれないと思ってたんですが じゃあ皆さんはイテレータが指してるコンテナのことはなんて呼んでるんでしょう 「イテレータが指してるコンテナ」ですか?
572 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 01:24:23 ] イテレータが指してるコンテナ? vector<int>::iterator it; だと vectorが「イテランド」になんの?
573 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 01:27:10 ] 例えば vector<int> v; vector<int>::iterator it = v.begin(); なら、itはvのイテレータで、vはitのイテランドです
574 名前:デフォルトの名無しさん mailto:sage [2008/11/21(金) 01:38:03 ] iterateeとか言ってみる。