[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 2chのread.cgiへ]
Update time : 06/27 01:24 / Filesize : 192 KB / Number-of Response : 847
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

【C++】STL(Standard Template Library)相談室 9



1 名前:デフォルトの名無しさん [2008/02/27(水) 02:03:30 ]
C++標準ライブラリの一つ、STLについて。

前スレ
【C++】STL(Standard Template Library)相談室 8
pc11.2ch.net/test/read.cgi/tech/1198435319/

過去ログ・リンク・書籍紹介は >>2 以降

577 名前:デフォルトの名無しさん mailto:sage [2008/05/28(水) 22:57:16 ]
>>576
ありがとうございます
エラーは出なくなりました。

でも、 typename がなぜ必要なのかわかりません。
どこを調べたらいいのでしょうか?

578 名前:デフォルトの名無しさん mailto:sage [2008/05/28(水) 23:14:34 ]
>>577
一度、Effective STLを読んでおいた方がいいんじゃないか?

579 名前:デフォルトの名無しさん mailto:sage [2008/05/28(水) 23:20:22 ]
>>577
www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=C%2B%2B+template+typename&num=50

580 名前:デフォルトの名無しさん mailto:sage [2008/05/28(水) 23:22:34 ]
型なのかメンバ変数なのかハッキリしろコラァ!
とコンパイラが怒るから

581 名前:デフォルトの名無しさん mailto:sage [2008/05/29(木) 10:23:16 ]
この文脈では list<T>::iterator のTは型に決まってるだろ、と小1時間ほど問い詰めてやりたい


582 名前:デフォルトの名無しさん mailto:sage [2008/05/29(木) 10:31:12 ]
Tじゃなくて、iteratorが型かどうかわからない。

583 名前:デフォルトの名無しさん mailto:sage [2008/05/29(木) 11:24:32 ]
template<typename T> struct list{ enum{ iterator = 0 }; };
だったらlist<T>::iteratorをする時にはtypenameの代わりに何が必要なのか

584 名前:デフォルトの名無しさん mailto:sage [2008/05/29(木) 12:45:15 ]
>>583
何もいらない。
typenameがないときは、暗黙のうちに値として扱われるよ。例外もあるけど。

585 名前:デフォルトの名無しさん mailto:sage [2008/05/29(木) 12:50:33 ]
>>581
実際VC++だとtypename無くても通るっぽい?
賢いというよりテンプレート宣言を読むときは「あーはいはい」って感じで
実際に型当てはめてからチェック開始してるのかね



586 名前:デフォルトの名無しさん mailto:sage [2008/05/29(木) 19:36:19 ]
>>582
なるほど、
typename list<T>::iterator m_iter;
は list<T>::iterator がタイプ名だとコンパイラに教えているのか
やっと納得できた


587 名前:デフォルトの名無しさん mailto:sage [2008/05/30(金) 01:04:10 ]
C++続けるつもりなら読むべきものをまず読んどけ

588 名前:デフォルトの名無しさん mailto:sage [2008/05/30(金) 02:06:07 ]
SICPですね、わかります

589 名前:デフォルトの名無しさん mailto:sage [2008/05/30(金) 02:43:43 ]
SICPとはまた時代遅れの物を

590 名前:デフォルトの名無しさん mailto:sage [2008/05/30(金) 22:33:28 ]
TR1のお勧め参考書おしえてくれ

591 名前:デフォルトの名無しさん mailto:sage [2008/05/30(金) 22:40:10 ]
>>590
つTechnical Report 1

592 名前:デフォルトの名無しさん [2008/05/31(土) 01:30:22 ]
ちょっと質問です。

STL辺りに「テーブルクラス」なんてありますか?
イメージとしては、データベースのテーブルをオブジェクトとして扱うクラスです。

result = DBDATA.summary(var1) ;
こんな感じです。

593 名前:デフォルトの名無しさん mailto:sage [2008/05/31(土) 02:36:59 ]
>>590
EffectiveC++の第三版はtr1にちょっと触れてる

594 名前:デフォルトの名無しさん mailto:sage [2008/05/31(土) 07:56:28 ]
>>592
イメージとしては、データベースのテーブルをオブジェクトとして扱う
クラスはない感じです。

595 名前:デフォルトの名無しさん mailto:sage [2008/05/31(土) 12:12:08 ]
>>592
STLだけでやるなら、連想系コンテナとアルゴリズムを組み合わせる感じかね。



596 名前:デフォルトの名無しさん mailto:sage [2008/05/31(土) 12:19:01 ]
>>590
とりあえずboost本買ってみるのは

597 名前:デフォルトの名無しさん mailto:sage [2008/05/31(土) 14:49:33 ]
>>592
where句が限定されているならmapでいいんじゃないの?
っていうかDB的に使うなら普通にsqliteでも使った方が無難だよ。


598 名前:デフォルトの名無しさん mailto:sage [2008/05/31(土) 15:20:14 ]
O/Rマッパーが欲しいんじゃね
DataSetとか

599 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 22:37:03 ]
mapは、要素の追加または削除を行ってもそれ以外の要素の参照は保たれたままな事が保証されていますか?

600 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 22:38:01 ]
追記です。要素への参照の他に、キーのについても同じ事が言えますか?

601 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 22:40:26 ]
自己解決しました。ありがとうございました。

602 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 23:09:11 ]
死ね

603 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 23:43:37 ]
死ねっていう奴と
死ねって言われた奴は
死ねばいいのに

604 名前:デフォルトの名無しさん mailto:sage [2008/06/03(火) 23:59:17 ]
そして伝説へ・・・

605 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 00:06:56 ]
死んでもそれ以外の人の参照は保たれたままな事が保証されていますか?



606 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 01:00:47 ]
死して屍拾う者なし、ってメモリリークのことですか?

607 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 08:44:19 ]
GC「骨くらいは拾っておいてやるよ」

608 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 08:45:30 ]
デストラクタ「生ける者の為の卒塔婆」

609 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 13:11:39 ]
std::mapのイテレータに順ずるものから、木構造の右部分木、左部分木をそれぞれ取得して
木を追跡したいんですが、そういうことは可能でしょうか?

610 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 13:13:10 ]
赤黒木使ってたら左部分木と右部分木だけとは限らないよ
アルゴリズムの本読んでみ

611 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 13:17:24 ]
>>609
std::map が木で実装されているとは限らないので、そういう操作は無い。

木の追跡(?)自体がやりたいわけじゃないと思うんだけど、結局のところ何がしたいの?

612 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 13:26:33 ]
>>611
upper/lower_boundで解決しました。

613 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 13:36:39 ]
やっぱり解決しませんでした。もういいです諦めます。STL死ね。

614 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 13:41:17 ]
お前が死ね

615 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 14:21:17 ]
すぐファビョる所を見ると朝鮮人か



616 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 14:23:03 ]
私が死ぬのであなた達は死ななくてもよいのです

617 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 15:05:12 ]
STLは生き物ではないので死ぬことはできません

618 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 15:18:03 ]
私のお墓の前で泣かないでください

619 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 15:46:50 ]
STLの考え方に頭が付いていかない所を見ると
頭が悪いかジジイかのどちらかだろう

620 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 16:07:29 ]
お尋ねします。
vector<vector<bool>> TempA;
vector<vector<bool>>::iterator itr1;
vector<vector<bool>>::iterator itr2;
と宣言したとします。
itr1 = TempA.begin();
itr2 = TempA.begin();
としたのち、
TempAのたとえば2行目と3行目の中身すべてを比較したいとき、
itr1++;itr2 += 2;としてiteratorを進めて、
*itr1 == *itr2の比較を一度行えばいいのでしょうか?
それとも、各行でiteratorを作成して、
各行ベクトルの列座標に対応したiteratorを回す必要がありますか?

p.s.この動作のあと、一致している行を、
itr2=Temp.erase(itr2);
みたいに削除したいのです。

621 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 16:34:38 ]
>>620
要するに二つのvectorを==で比較できるかってことだよな
できるよ

622 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 16:46:22 ]
>>621
ありがとうございます。
行に対応するvectorの各要素の比較という認識で大丈夫でしょうか。

623 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 18:17:13 ]
そう。要素ごとに==で比較してる

624 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 18:19:40 ]
>>622
23.1 Container requirements に
a == b は a.size() == b.size() && equal(a.begin(), a.end(), b.begin())
と等価と書いてある。

625 名前:デフォルトの名無しさん mailto:sage [2008/06/04(水) 22:12:31 ]
>613
map使わずにソート済vector使えばいいんじゃね?



626 名前:620 mailto:sage [2008/06/05(木) 10:43:24 ]
>>623
亀レス申し訳ない。
ありがとうございました。

そういう情報ってどのヘッダーを見ればいいんでしょうか?
vector.hを眺めていてもさっぱりです…。

627 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 11:34:56 ]
>>626
ヘッダーには書いてないだろう・・・
お使いのコンパイラのリファレンスマニュアル等を読め
VCならこのへん↓
msdn.microsoft.com/en-us/library/5asks2ba(VS.80).aspx

628 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 13:25:16 ]
>>626
C++の規格書一回読んでみるのもいい。

629 名前:デフォルトの名無しさん mailto:sage [2008/06/05(木) 20:20:37 ]
vectorかその内部でincludeしてるファイルに書いてあるんじゃね。実装が。

630 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 10:17:16 ]
イテレータを返すbegin, endが、どうして戻り値の型が違うだけで(iterator, const_iterator)オーバーロードされた関数を特定できるのかが分かりません。
自分で同じ様な事をしようとしてもSTLとは違いコンパイラが関数を特定できずに失敗します。

631 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 10:22:06 ]
>>630
戻り値の型じゃなくて、引数リストの後ろの const の有無が違う。

632 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 10:36:05 ]
>>631
それは実装側のbegin, endの定義ですよね?
自分で作ったものもconst_iteratorを返すものは引数リストの後にconstをつけているんですが、
これは利用する側が呼び出すときには特に関係ない様です。
まさか container_type::const_iterator it = ((container_type::const_iterator (container_type::*)()const)container.begin)();
なんてしなきゃいけないんですか?

633 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 11:24:47 ]
iteratorからconst_iteratorへの変換はできるようになってる?

634 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 11:27:59 ]
変換できるようにしたら const_iterator begin() const の必要性なくならないか?

635 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 11:31:44 ]
なんで?
constなインスタンスに対してイテレータ取得できなくなっちゃうじゃん



636 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 12:59:04 ]
VC7

template<class _Ty,class _Alloc>
class _Vector_iterator : public _Vector_const_iterator<_Ty, _Alloc>

637 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 19:44:07 ]
>>636
補足しとくと、iteratorは基底クラスであるconst_iteratorに変換できるといいたいだけ。
constなしbegin()の戻り値はiteratorだからconst_iteratorにも変換されうる。

begin()の戻り値を渡す先がconst_iteratorかiteratorかで、
begin()の種類(後ろにconst付きか否か)が選択されているわけじゃない。

638 名前:デフォルトの名無しさん mailto:sage [2008/06/06(金) 22:14:29 ]
>>632
MyContainer c = ...
MyContainer const& cc = ...
MyContainer::const_iterator = c.begin();
MyContainer::const_iterator = cc.begin();

これをトレースするといいよ。

639 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 00:30:21 ]
なるほど、constなメンバ関数はオブジェクトがconstな時に使用されるんですね。

640 名前:デフォルトの名無しさん mailto:sage [2008/06/07(土) 13:26:16 ]
constメンバ関数と非constメンバ関数が両方ともある場合はそうなる。
非constメンバ関数がない場合は非constオブジェクトからもconstメンバ関数が呼ばれる。

641 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 20:31:07 ]
\n とか \r\n とかが入った文字列を SetDlgItemTextすると
char のときはちゃんと改行してるのに string だと改行されずに何も表示されないわけですが
string って \n とかとは別に改行とかタブコードがあるんでしょうか?

642 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 20:40:55 ]
実際のコード貼ってみれ

643 名前:641 mailto:sage [2008/06/13(金) 21:37:36 ]
あははははは!!!!!
エディットコントロールのマルチラインがFalseなだけだった
俺市ねw

644 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 22:13:13 ]
641は死んだの?

645 名前:デフォルトの名無しさん mailto:sage [2008/06/13(金) 22:49:25 ]
>>644
今日までの641は氏に、また一歩成長したプログラマーとして生まれ変わるのです。



646 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 12:34:34 ]
>>645が良い事言った

647 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:25:44 ]
フェニックスシングルトンなわけですね。

648 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:30:12 ]
シングルトンを真面目に考えるとややこしい事限りないなあ。

649 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:31:25 ]
非常に優秀なデザインパターンの1つだと思うな

650 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:36:29 ]
インスタンスの数が1個に限定される分、むしろ単純にならないか?

651 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:39:16 ]
Modern C++ Design を読むと
シングルトンのややこしさがよく分かる。
Scala みたいに言語的にサポートしてくれればいいんだが。

652 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:48:11 ]
作るのはいいけど削除のタイミングが面倒くさいんだよね。

653 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:53:21 ]
いつでもnewdelete出来るように改良した、って自慢げに変なシングルトン使いまくる奴ならいたな

654 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 15:58:26 ]
deleteしたら自動的に新しいインスタンスが作られて、
newしたら自動的に今あるインスタンスが削除されるシングルトン

655 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 16:51:25 ]
>言語的にサポート
使う人間のスキルへの依存度が高いC++に期待してはいけないものだよ。



656 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 16:59:25 ]
シングルトンて心太に似てるよね

657 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 18:36:28 ]
STLを軽く弄るためにこのスレを覗きにくるC++ビギナーはフェニックスシングルトンとModernC++Designをどうやって関連付けて考えるだろうか。

658 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 18:37:22 ]
「スレ違い」 と関連づけて考える事だろう

659 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 19:42:54 ]
mapはどうやってfindなどで入力されたキーが木にあるキーと同じかどうかを見るんでしょうか?
比較関数ならstd::less<T>がデフォルトで入っていてこいつを使えば良いと分かるんですか、
これと同じ様に一致関数をテンプレート引数で指定できませんか?

660 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 19:45:23 ]
比較関数をltとすると、
!lt(x, y) && !lt(y, x)
で一致判定してる

661 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 19:46:43 ]
マップのキーは、その比較関数を使って一致を判断する
!(a < b) && !(b < a) なら a と b は一致していることになる

662 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 20:12:24 ]
そして等価と等値の話が始まる。

663 名前:デフォルトの名無しさん mailto:sage [2008/06/14(土) 22:07:44 ]
重要な概念だしな

664 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 09:53:59 ]
そしてEffective STL が売れる

665 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 10:08:08 ]
そして日本語版Modern C++ Designが叩かれる。



666 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 15:05:30 ]
ListとかVectorってスレッドセーフですか?
複数のスレッドからイテレータ取得してアクセスしたりするなら
シグナルやミューテクスでロックしてからアクセスするべきですか?


667 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 15:10:46 ]
そうですね。

668 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 15:16:56 ]
>>666
実装次第。
各処理系のマニュアルを読むよう。

669 名前:デフォルトの名無しさん mailto:sage [2008/06/15(日) 15:29:14 ]
STLportでぐぐらない方が良い。

670 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 20:02:10 ]
スレッドセーフなのか?という問いに答える者はいなかったといふ


671 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 20:04:49 ]
実装次第だし。

672 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 20:09:48 ]
スレッドセーフではない と一律で答えておいたほうが面倒がない

673 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 21:24:55 ]
Camelなリストやベクタはスレチ。

674 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 21:43:27 ]
というか、「スレッド」の概念が標準C++にあるんだっけ?

675 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 21:54:49 ]
ございません



676 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 22:07:35 ]
スレッドの概念が無いから「スレッドセーフでない」という概念も無い。

677 名前:デフォルトの名無しさん mailto:sage [2008/06/17(火) 22:15:17 ]
C++0xにご期待下さい

678 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 02:26:33 ]
>>670 >>531-540

679 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 22:08:47 ]
コンテナの範囲外にイテレータがインクメントされてしまってもコンテナを自動で拡張し、
あたかも未だに範囲内を指している様に振舞うイテレータってのがあると思うんですけど
実際はなくてただの思い過ごしだったりしますか?しなかった場合はそれが何なのか教えてください。

680 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 22:22:49 ]
insert_iteratorのことを言ってるのかな。

681 名前:デフォルトの名無しさん mailto:sage [2008/06/18(水) 22:35:13 ]
自己解決もしたし意味不明な書き込みなんてみんな無視してくれるだろうと思っていたら教えてくれている人が居た。
ありがとう。

682 名前:デフォルトの名無しさん [2008/06/20(金) 15:05:13 ]
std::vector<std::string> v1;

みたいなインスタンスをシリアライズ化したいんですけど、単純に

FILE *fp = fopen("vec.bin", "wb");
fwrite(&v1, sizeof(v1), 1, fp);
fclose(fp);

みたいに書き込めば良いんですかね?
そして戻すときは、逆に

std::vector<std::string> v1;
char* buf = (char*)&v1;
FILE *fp = fopen("vec.bin", "rb");
while(fread(buf++, 1, 1, fp) > 0);
fclose(fp);

みたいな感じでいいんですかね?
STLのインスタンスのシリアライズ化で、もっと適切な方法があったら教えてください。

683 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 15:33:55 ]
vectorの内部にはポインタも含まれるから
オブジェクトの性質を考えてPOD型のデータまで落としこまないとダメだろう

684 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 15:38:38 ]
vectorの扱う型ががフリーストアを使ってないという保証があればあるいは

685 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 15:46:36 ]
boost::serialization使うって手も <あまり使いやすくは無い



686 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 16:45:27 ]
VS2005では一応下のコードは正常に動きました。
とりあえずこれが動けば十分です。

std::vector<std::string> v1;
v1.clear();
v1.push_back("要素1");
v1.push_back("要素2");
v1.push_back("要素3");
FILE *fp;
fopen_s(&fp, "vec.bin", "wb");
fwrite(&v1, sizeof(v1), 1, fp);
fclose(fp);

std::vector<std::string> v2;
char* buf = (char*)&v2;
fopen_s(&fp, "vec.bin", "rb");
while(fread(buf++, 1, 1, fp) > 0);
fclose(fp);

687 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 16:53:25 ]
>>686
まてまて、それv1の確保したメモリアドレスをv2が指しているだけだろ。
終了時に2重解放でエラーになってないか?

688 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 16:54:48 ]
と思ったら、デストラクタで怒られました。
何がいけないんだろう・・・

689 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 16:58:00 ]
上の人も書いてるけどvectorは内部にポインタを持ってるんだってば。
(ついでにstringもな)
fwriteでv1を直書きすると、ポインタのアドレスが保存されるだけで、
ポイント先は保存されないんだよ。

690 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:00:54 ]
>>687,689
どうすればいいでしょうか。

やりたいことは、カンマ区切りで並んでいる大量の文字列データがあって、
それをカンマの区切りを探しつつ読み込むと非常に時間がかかるので、
初回だけカンマ区切りを解釈したら、その後はインスタンスをバイナリで一気に保存、一気に復元したいのです。

691 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:04:45 ]
vector使わずに配列を使えばいいんでしょうが、vectorのデータをシリアライズ化するということは
ニーズとしてあるはずなので、そういう手法があれば教えていただきたいのです。
ただシリアライズのためにboostという別ライブラリを使用するのは、ちょっと大げさすぎかなと。。
そこまでするなら配列でやります。

692 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:10:08 ]
自分の力量・理解度に応じた実装をするべし

693 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:11:11 ]
最低限のデータを保存したい場合はこうじゃない?

std::vector<std::string> v1;
v1.clear();
v1.push_back("要素1");
v1.push_back("要素2");
v1.push_back("要素3");
FILE *fp;
fopen_s(&fp, "vec.bin", "wb");
const char *pstr;
fwrite(&v1.size(), sizeof(size_t), 1, fp); //読み込むときの利便を考えて要素数を保存
for(size_t c=0, e=v1.size(); c < e; c++) {
 pstr = v1[c].c_str();
 fwrite(pstr, strlen(pstr), 1, fp);
}
fclose(fp);


694 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:21:42 ]
stringのサイズ保存してなかったので訂正
書き込み

std::vector<std::string> v1;
v1.clear();
v1.push_back("要素1");
v1.push_back("要素2");
v1.push_back("要素3");
FILE *fp;
fopen_s(&fp, "vec.bin", "wb");
fwrite(&v1.size(), sizeof(size_t), 1, fp); //読み込むときの利便を考えて要素数を保存
size_t size;
for(size_t c=0, e=v1.size(); c < e; c++) {
 size = v1[c].size();
 fwite(&size, sizeof(size), 1, fp);
 fwrite(v1[c].c_str(), size, 1, fp);
}
fclose(fp);

695 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:28:10 ]
読み込み

std::vector<std::string> v2;
FILE *fp;
fopen_s(&fp, "vec.bin", "rb");
size_t size;
fread(&size, sizeof(size), 1, fp);
v2.resize(size);
for(size_t c=0, e=size; c < e; c++) {
 fread(&size, sizeof(size), 1, fp);
 v2[c].resize(size);
 fread(&v2[c][0], size, 1, fp);
 //stringの確保するメモリが連続してない環境なら、一度vectorなりに読み込む必要が
 //あるが、vcなら問題ないので省略
}
fclose(fp);



696 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:33:26 ]
最初にもちらっと書いたが、serialization使うとこれですむ

//保存
{
vector<string> data;
data.push_back("Hello");
data.push_back("World");

ofstream file("save.dat");
boost::archive::text_oarchive oa(file);
oa << (const vector<string>&) data;
}

// 復元
{
vector<string> data;

ifstream file("save.dat");
boost::archive::text_iarchive ia(file);
ia >> data;
}

下準備がちょっと面倒だけどな。
興味あったら下記を参照してください。
ttp://www.kmonos.net/alang/boost/classes/serialization.html

697 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:48:04 ]
>>694,695
やっぱり要素ごとにサイズと一緒に保存という形しかないんでしょうか。
私のイメージではシリアライズというと、メモリ上にあるオブジェクトの塊を
そのままバイナリで一気に書き込むという感じで、だからこそ高速化に役立つと思うのです。
要素ごとに書き込んでいると、カンマ区切りのケースとそれほど時間の差が出ないような・・・

MFCのCObjectを継承したクラスはシリアライズができますが、それはおそらく、
オブジェクトのデータやステートをメモリ空間上で一塊になるようにしている配置しているからこそ
できるんじゃないかと思います。

STLではどうもそういう仕組みはないようなので、保存や復元に時間がかかるのは無理ないんでしょうかね。。。

>>696
boostの場合はどうなんでしょうか。
保存と復元を高速化できるかどうかがキモなんです。

698 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 17:55:59 ]
>>690
カンマ区切りの文字列の読み込みに、そんなに時間がかかるとは思えんが。
時間がかかっているのはパースよりもvectorの伸張だろう。

先にカンマの数をカウントしてvector.reserve()するとか、vectorではなくて
dequeにするとかの方が速くなるかと。

699 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 18:06:48 ]
>>697
MFCのシリアライズは、各メンバをひとつずつCArchiveに書き込んでたと思うよ
CObjectを継承すれば自動的にサポートされるものでもなく、メンバをひとつずつ書き込むコードを各クラスに個別に実装する必要があった
シリアライズに対するそのイメージは誤りかと

700 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 18:31:32 ]
データ個数にもよるが保存と読み込み時間を短縮したいなら
まずデータ構造自体から見直すべきだろ。
というか、そこがネックになってる時点で何かが間違ってる。

701 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 18:44:43 ]
>>699,700
そうなんですか。
可変長データ配列のオブジェクトの保存と復元を高速化するためには、
各自が工夫して実装するしかないんですかね。
なんか車輪の再発明のような気が・・・

配列要素の変更・追加・削除は頻繁にはやらないので、そちらの時間コストは多少増えてもいいんです。
とにかくソフトの起動をコンマ1秒でも速くするために、ドカンと一気に読み込めるようにしたいんですよね。
BYTE型配列1本と、ポインタ・サイズを格納した配列の計2本で、
そういったことをやれそうなイメージはあります。

702 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 18:45:42 ]
vector<string>が固定長なデータじゃないので、要素ごとにアクセス
しなければならないのは仕方が無い。
また、上の例でも1文字ずつカンマをチェックしながらアクセスするよりは、
単純に数倍は速いよ。
ディスクアクセスが気になってるのなら、あらかじめメモリ上に
直列化して、総サイズも一緒に書き込むとか工夫しなさい。
(もともとfread、writeがバッファリングしてるので、あまり効果は無いだろうけど)


あとboostのも1要素ごとの読み書きです。
入れ子になってるコンテナの巡回探査がデフォで出来るってだけ。

703 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 20:42:53 ]
ほんとに直列の読み書きがしたければAPI叩くしかないんじゃないかなあ

704 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 20:59:26 ]
>>701
まぁ今回の件に限らず、「コンマ1秒でも速くする」というような目標を持っている場合、
車輪の再発明は避けられないことが多いよね(そうでない場合も勿論あるけど)。

705 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 21:01:24 ]
本当に速くしたいなら MMX とか SIMD とか使うと



706 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 21:54:44 ]
DANGOさんの出番だな

707 名前:デフォルトの名無しさん mailto:sage [2008/06/20(金) 22:09:39 ]
: premature optimization is
(省略されました。続きを読むにはワッフルワッフルと書き込んでください)

708 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 01:24:43 ]
ポインタのない言語なら>>686みたいなことは当たり前にできるんだけどな。
ポインタのある言語では、一気に話が複雑になるな。

709 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 06:23:29 ]
データの入出力なんて元々複雑で時間の掛かる処理なんだから
横着するつもりなら効率の劣化には目を瞑るべき。
大体そんな困るほど遅くなることなんぞ滅多に無いし。

710 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 12:47:42 ]
だいたい直列化してないデータを直列させるからシリアライズと
いうのに、最初からメモリ上に直列に並んでると考えるのはどうなのよw

711 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 12:51:19 ]
>>708
ポインタの無いJAVAみたいな言語だって、>686みたいな記述はできても、
要素の実際の読み書きは1つずつだろ?

712 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 14:46:07 ]
>>686
これは素晴らしい!!!
すこぶる高速ですね

713 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 14:49:44 ]
>>686
これstringの実装によってはやばくないのかな

714 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 15:00:33 ]
>>686
こんな気持ち悪いコード見たことない

715 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 15:01:03 ]
>>713
そのコードがダメなのははっきりしてるから。
続きも読め



716 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 15:01:06 ]
それ以前の問題。

717 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 15:42:55 ]
ポインタ保存してポインタ復帰してるだけだからな。

718 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 16:59:18 ]
>>709
いや、プログラムの起動を可能な限り速くしたいというニーズはどこにでもある。
3秒で起動するブラウザと1秒で起動するブラウザ、どっちを使いたいかといえば速い方がいいに決まってる。

そういう場合のクラスデータのシリアライズは、1分かかるのを30秒にしたいとかいうオーダーの話ではなくて、
0.3秒かかるのを0.05秒に縮めたいとかいうオーダーなんだよ。
起動時にデシリアライズするオブジェクトの数は1つじゃないしな。

トータルで1秒以内で起動させたいとか、そういうレベルのことをやりたいとなると、
バイト配列の中に直列化したデータ(多少隙間があってもいい)をあらかじめ揃えておいて
一気にシリアライズするという考えも、アリだと思う。

719 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 17:02:02 ]
ファイル読み書きのオーバーヘッドなんてI/O待ちが大半なんだから、
よっぽどアホな処理でもしてない限り大差ないだろ

720 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 17:09:11 ]
>>718
さっきドラゴンボール全巻買ってきた までは読んだ


:そこ、高速化したいなら横着せず書かないといけないって書いてんじゃん

721 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 17:38:07 ]
その手のオーバーヘッドで一番時間食うのはstatだったりするんだよな

722 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 17:46:02 ]
>>718
将来まで不変のデータ構造ならいいけど、
少しでも変えると過去のバージョンで直列化したデータが読めなくなるよね。
(すべてのバージョンに対するコンバータを付けるのもどうかと思うし)
痛し痒しだなぁ。

723 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 18:12:43 ]
ちゅーか目的が高速化なのに質問者が面倒がって
既存の実装使おうと食い下がってるだけだじゃん。

724 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 18:28:07 ]
既存の実装で高速化できないってことは既存の実装がクソだということですよね

725 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 18:35:28 ]
F-1を公道に持っていったら全く使い物にならないのと同じ。
普通車なら速くはないが大体どこでも走れる



726 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 19:27:12 ]
>>724
べっ別にあんたのために実装したんじゃないんだからね。

すべてに効果のある実装は存在しない。自分の目的に合う実装がなければ自分で作る。

727 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 19:39:42 ]
暇だから素のテキストと長さ情報付きのバイナリで試してみた。

入力データはwindows.hおよびそこからincludeされているファイルから抽出した
全て大文字の先頭以外にアンダーバー入りの定数マクロ(WM_hoge等)18364個。
文字列の平均の長さは20.8文字。
手抜きのために、カンマ区切りではなく改行区切りで保存。

テキスト(ifstream.getline()で読み込み)
vector<string> 23ms
deque<string> 21ms
list<sting> 21ms

バイナリ(ifstream.read()で読み込み)
vector<string> 14ms
deque<string> 12ms
list<sting> 12ms

ちなみに、VC++2008Stdでコンパイル、E8400のPCで実行。
全て複数回実行した中で一番速かった結果。

728 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 19:54:00 ]
freadに変えればさらに速くなるぜ

729 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 23:43:18 ]
ifstreamをやめて、fopen,fgets,freadにしてみた

テキスト(fgets()で読み込み+改行コード除去)
vector<string> 14ms

バイナリ(fread()で読み込み)
vector<string> 14ms


CreateFile,ReadFileも試してみた

テキスト(2048バイトずつ読み込み)
vector<string> 11ms

バイナリ(必要なサイズだけ読み込み)
vector<string> 100ms

730 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 23:47:59 ]
つーかstringって時点でバッファに直読みできねーよな
CString::GetBuffer()使ってみ

731 名前:729 mailto:sage [2008/06/21(土) 23:51:07 ]
結局、ifstream.getline()が遅いだけで、読み込み部分を最適化したら
テキスト形式でもバイナリ形式でも差がない感じ。

ちなみにテキスト形式でファイル一気読みでは、稀に10msが出る程度。

あと、バイナリ形式でReadFile()でチマチマ読むのは何故か遅かった。
fread()は速いのにね。

732 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 23:51:41 ]
それはスレ違い。

733 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 23:56:05 ]
>>731
それは「何故か」でも何でもなく明らかなことだ
fread()はチマチマじゃなくて「一気に」バッファに読み込んで
読み込んだ分だけユーザに渡してるから速いんだよ

734 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 23:57:47 ]
>>732
スレ違いかもしれないが重要なことだろ。
stringに高速にデータを読み込む方法は存在しない。
必ずコピーが発生するのだから。

カーネルバッファ→stdioバッファ→ユーザバッファ(典型的にはchar[])→string
こんな感じ

ほらみろ、効率悪い

735 名前:デフォルトの名無しさん mailto:sage [2008/06/21(土) 23:59:58 ]
stringの実装を知っていれば環境依存の方法で…
ってもうSTL作者になる以外ないな



736 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:00:38 ]
>>730
この場合だと、GetBuffer使うメリットねーと思う。

737 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:01:56 ]
>>736
いーやある。
fread()ではstringに直接読み込めないので一時的にchar[]に読み込んでコピー
するしかないが、
CString::GetBuffer()ならfreadで直接読み込める
つまり、一段コピーを減らせる

738 名前:736 mailto:sage [2008/06/22(日) 00:03:33 ]
>>737
理由は>>733が書いてる。GetBufferつかったら、それ以上に読み込み遅くなるだろ。

739 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:05:30 ]
>>738
は?何言ってんの。
CStringで適当なサイズをリザーブしといて、
GetBuffer()で取ったchar*のポインタにfread()しろっつってんだぞ?

間違いなくchar[]に読み込んでからstd::stringにコピーするより
速いよ。

740 名前:739 mailto:sage [2008/06/22(日) 00:09:03 ]
ああ、話のズレがわかった。
俺はstd::stringなんて使わなきゃ速いよつってるんだ。

最後にstd::stringにコピーしなきゃならないんなら意味ないわな、
そりゃ。
コピー君だもの。

741 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:11:10 ]
単に速いだけの話しならstd::istreambuf_iteratorとstd::ostreambuf_iterator
が速いんじゃないの?書式化なしだし

742 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:12:10 ]
>>739
いってることはりかいできるけど、俺が言いたかったのはそうじゃない。

俺が言ってるのは、読み込んだデータには
複数のデータ(複数の文字列と文字列サイズのペア)が格納されてるってことだ。
んで、>>686あたりからの流れのように、vectorに一個一個格納すると。

まあすれ違いだからもう自重する。

743 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:12:33 ]
>>741
それはどんだけ頑張ってもマクロ版のgetc()/putc()と同等の速度で、
言うまでも無くfread()より遅いよ

744 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:12:56 ]
またEffective STLを読み返さねばならんようだな

745 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 00:27:04 ]
>>743
そりゃそうだ
比べるのが無謀
というか比べるな



746 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 01:02:51 ]
std::stringのかわりにstd::vector<char>つかえばいいんじゃね

char*, const char*のかわりに使えるし
STLやboostのiterator取るタイプの関数も全部使えるし
std::stringと違ってバッファ直接書き換えできるよ

747 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 01:04:21 ]
どんだけ頑張ってもAPI直書きより
遅い。


748 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 01:10:19 ]
>>747
上に出てるように、ちまちまReadFile()を呼ぶようなアホなまねをやるぐらいなら
まだfread()のほうが速いよ

749 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 01:11:46 ]
もうRAMDisk使います

750 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 01:17:54 ]
一応言っとくけど、バッファ渡して書き換えてもらう系の
関数だのAPIだのを使う際には全てこの議論は当てはまるんだぜ
別にI/Oだけの問題じゃない

std::stringを使っている限りは常にコピーがワンクッション入ることを
覚悟せよってこった
通常はどうでもいい問題だがな

751 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 01:57:38 ]
あーつまり何だ?
ドライバ書けと

752 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 01:59:57 ]
tcpのread/writeでのコピーは減るように各OSがんばってるネー

753 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 02:07:28 ]
x86はリトルエンディアンであるというだけでtcp/ipのビッグエンディアンを
実現するのに少し不利なんだよな

754 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 02:07:52 ]
物理層じゃなくてアプリケーション層の話な

755 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 02:08:10 ]
データ本体だからendianは関係ないのでは・・



756 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 02:21:07 ]
データをストアする時にひっくり返るでしょう
ブラウザはどういう仕組みになっているのか知らないが
Unicodeをリトルエンディアンのまま画面出力できるようになっているのか、
それともビッグエンディアンに並び替えて表示しているのか

757 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 02:56:12 ]
速度最重視ならLEで送ってもらうんでないの

758 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 02:58:27 ]
OSネイティブの文字コードで送られてくることなんか超レアケースだろ。そんなところが
最適化されててもたいしたメリットは無い。

759 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 08:20:06 ]
保存したファイルを直接ファイルマッピングして、そのまま利用するのが最速なんじゃね
要するにオンメモリでの利用形式を、保存形式に合わせるw

760 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 09:06:23 ]
>>759
ファイルマッピングはファイルサイズを伸ばせないのが難点だな。何かいい方法がないものか。

761 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 09:50:40 ]
>>759
ReadFile()やWriteFile()は別にディスクをガリガリ読み書きする
わけじゃなくて、オンメモリのバッファキャッシュが相手だからな
事実上裏でOSがページ単位でファイルマッピングしてるのと同じで
CreateFileMapping()したからつって経験上別に速くならないよ
Windowsではな

話を大幅に戻すと、小手先の最適化に走る前に、本当にCSVやvector<string>
じゃなければいけないのかってところを考えるべきだと思うね

固定長データ、ISAM、SQLite、Berkeley DBのようなものが適切なんじゃないかとかさ

762 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 16:22:09 ]
fopenは、内部的にReadFileを呼び出しているものの、バッファリングしているので
(普通に使う分には)充分な速度が出る。
ただし、複数回のコピーが無駄と言えば無駄。

ReadFileは、OSのバッファにキャッシュしていてディスクアクセスはしないものの、
システムコールだから、カーネルとのスイッチが発生する。
だから、細かく何度も呼び出すと非常に遅くなる。

CreateFileMappingと使うと、OSのバッファキャッシュを経由しないので
ゼロコピーとなり、読み出しに限れば最速を期待できる。


書き込みは、普通はバッファリングされるfwriteを使うべき。
Readと同様、直接APIを叩いても大して効果ないし
逆にバッファリングを無効にすると、ディスクアクセス完了まで待たされることになる。

この場合にどうしても最速を求めるなら、非同期APIを使う。

763 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 16:52:11 ]
俺、この類はcatコマンドのソース読んで参考にした。
読み込みと、書き込み(表示)について練り込まれた結果の
知識が詰まってるなと思った。 ちなみに read() write() 使ってた。

764 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 17:36:20 ]
あ、そうだ。

stdioはバッファリングしてるけど
fgetc/fputcのような、1文字入出力系は注意。

最近のVCとかは、マルチスレッド対応ライブラリで
1文字ごとにロックしているので、このコストがバカにならない。
遅いと言われるcygwinとかもそうかもしれない。

istream_iteratorとかは知らんが、MT対応を謳っているなら
ロックしている可能性は十分ある。

765 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 19:54:16 ]
iostreamの比較なんて昔から皆やってるのになぜいまさら



766 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 19:56:02 ]
実装が進化しているかもしれん。

767 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 20:17:58 ]
残念ながらstdioより速いiostreamなんてのは見たこともないし、今後も無いだろ。
実装の質の問題というよりは、仕様上無理なんじゃないか。

ios_base::sync_with_stdio()とかあるし、デフォでシンクロしてるのが仕様だから、
stdioをバイパスできず、stdioの上に構築せざるをえないってことになる。
おまけに仕様も複雑だ。
これでstdioより速くなるわけがないんだぜ。

768 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 20:23:36 ]
_CRT_DISABLE_PERFCRIT_LOCKS

769 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 22:22:47 ]
まあ、速さだけが基準じゃつまらんよな。

770 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 22:53:16 ]
>>697
そもそも
(世にある)シリアライズ機構 = 高速化のためのもの
という発想が間違い。

シリアライズ機構 =
ヘテロなオブジェクトの集合であっても、汎用的に直列表現に置き換えるための汎用枠組み
ととらえる方が常識で、(たとえば>>699みたいに)
でも汎用では自アプリにとっては遅くて不都合!という場合に、
自アプリに特化した、汎用無視の保存方法作る、というのがさらに常識。
CSVって決まってるならCSV特化とかね。そのかわりそこ変わった瞬間に大幅変更だけど。

771 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 23:19:12 ]
はぁ?手軽に最高速がC++の売りなんじゃないですかぁ?
バカなの?

ぶっちゃけRubyのほうが100万倍マシ

772 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 23:23:20 ]
>>771
はいはい、そうですね

773 名前:デフォルトの名無しさん mailto:sage [2008/06/22(日) 23:27:47 ]
C++が手軽なんて話は始めて聞いた

774 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 02:08:48 ]
最初に「100万倍」ってとこだけ目に入って、
あーきっとアホの子なんだろうなーと思って残りを見たら
完全にその通りだった。

775 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 03:37:07 ]
Ruby信者が例外なく全員キモイのは何故なんだろう



776 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 07:43:16 ]
Rubyは優秀な言語なのに、使ってる人の中身がDQNだからもったいないよなw

777 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 08:06:04 ]
釣りだったことにして逃げ切りを図るレスが来る頃合いだけど、
それを先にこうして予測したことで、ちょっとルートが変わるかもしれないな。

778 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 10:59:25 ]
いつも思うんだが信者がわざわざRubyの評判を落とすような事をするかな。

779 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 11:23:27 ]
儲に見えないのは俺だけか

780 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 11:55:36 ]
>>771-778は全て自演

781 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 13:00:25 ]
ということにしたいんですね

782 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 14:35:23 ]
>>778
例えば宗教団体の信者は熱心に勧誘を行って、結果周りから見るとイメージダウンをしている。
似たようなもんでは

783 名前:デフォルトの名無しさん mailto:sage [2008/06/23(月) 17:29:52 ]
そうかそうか

784 名前:デフォルトの名無しさん [2008/06/24(火) 20:00:11 ]
vectorの要素を指すポインタは無効になることがあります。
では、queueの要素を指すポインタは無効になることがありますか?
下のプログラムを実行すると、1 2 4 4 5 6 と出力され、期待通りに動きました。
このプログラムは正しいプログラムですか?

#include <iostream>
#include <queue>
using namespace std;

int main()
{
  queue<int> q;
  q.push(1);
  q.push(2);
  q.push(3);  int* x = &q.back();
  q.push(4);
  q.push(5);
  q.push(6);
  (*x)++;

  while (!q.empty()) {
    cout << q.front() << ' ';
    q.pop();
  }
  return 0;
}


785 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 20:11:36 ]
>>784
queueの中身のデフォはdequeなので、要素追加で
リアロケートが発生することがある。ポインタもイテレータも無効になる。





786 名前:784 mailto:sage [2008/06/24(火) 21:00:22 ]
>>785
なるほど。ありがとうございます。危ないところでした。

では、リストを使って、queue<int, list<int> > q;
とすればOKでしょうか?

787 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 21:30:01 ]
>>785
途中への追加はイテレータ等が無効になる可能性があるけど
端への追加ではイテレータ等は無効になんないんじゃないの?

788 名前:デフォルトの名無しさん mailto:sage [2008/06/24(火) 21:46:06 ]
>>787
> 23.2.1.3 deque modifiers
> An insert at either end of the deque invalidates all the iterators to the deque,
> but has no effect on the validity of references to elements of the deque.

イテレータは無効になるが、要素への参照は有効のまま。

789 名前:デフォルトの名無しさん mailto:sage [2008/06/25(水) 09:16:26 ]
>>786
vectorやdequeなら、イテレータではなく添え字でアクセスするのも有り。

790 名前:デフォルトの名無しさん [2008/06/28(土) 14:03:55 ]
algorithmのcopyについての質問です。

ifstream ifs(argv[1]);
vector<char> file;
copy(
 istream_iterator<char>(ifs.seekg(10, ios_base::beg))
 istream_iterator<char>(ifs.seekg(20, ios_base::beg))
 back_inserter(file)
);

上記のようなコードで、あるファイルの10バイト目から20バイト目までをコピーしようとおもったのですが、出来ませんでした。
このような事をする場合はどうしたらいいのでしょうか?

791 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 15:14:14 ]
>>790
int const begin = 10;
int const end = 20;

ifs.seekg(begin);
int const length = end - begin;
file.resize(length);
ifs.read(&file[0], length);

792 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 15:21:29 ]
>>791
ありがとう、だけどファイル以外のストリームに対しても同じ方法がとりたいとおもっているので、
algorithmのcopy、あるいはSTLの何かを使って解決したいのです。
で、思いついたのが790のコードなのです。

793 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 17:36:54 ]
>>792
>791 はファイル以外のストリームにも使えるんじゃないか?
seekg() ができないかもしれないってこと?

794 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 17:41:54 ]
そういや copy_n() ほしいな。

795 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 20:43:54 ]
どうでもいいけどistream_iterator<char>使うな
istreambuf_iterator<char>使え

istream_iterator<char>はoperator>>で入力するから、空白とか
スキップする。コピーにならんぞ



796 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 20:57:41 ]
どうでもいい割には念を押すね。

797 名前:デフォルトの名無しさん mailto:sage [2008/06/28(土) 21:09:48 ]
>>795
それ「どうでもいい」事じゃないと思うw

798 名前:デフォルトの名無しさん mailto:sage [2008/06/29(日) 22:25:50 ]
あげあしはどうでもいいよ。

799 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 00:24:58 ]
揚げ足取り、って言いたかったのかな。

800 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 00:30:10 ]
手羽先、って言いたかったんたと思うよ

801 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 01:44:47 ]
コケコッコーーー!!!

802 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 08:15:27 ]
お前ら鳥類食ってて何も恥じらいはないのかよ。
哺乳類としてのプライドはどこへ

803 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 08:54:17 ]
意味不明

804 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 09:01:33 ]
つーか、ヘビとかトカゲとか、哺乳類を食うのは許せないよな。
やつら爬虫類が生まれた頃にはまだ哺乳類も鳥類も居なかったってのに。
赤外線センサーまでつけやがって。

805 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 16:22:47 ]
面白いと思って書いてるのかな



806 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 18:24:07 ]
鳥類爬虫類は許せるが
鯨だけは愛と権利が与えられるべきだと思います


STL

807 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 18:27:03 ]
何故か日本より沢山偶然鯨が掛かる隣の国には抗議しません


808 名前:デフォルトの名無しさん mailto:sage [2008/06/30(月) 19:09:10 ]
何でこんな流れに

809 名前:デフォルトの名無しさん mailto:sage [2008/07/01(火) 21:42:20 ]
みんな鳥類食ってて何も恥じらいもないからだと思う

810 名前:デフォルトの名無しさん mailto:sage [2008/07/01(火) 21:49:13 ]
牛食うのは禁止すべきだろ。

811 名前:デフォルトの名無しさん mailto:sage [2008/07/01(火) 23:20:25 ]
人食いてぇ

812 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 02:02:12 ]
通報しますた

813 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 02:11:21 ]
考え方を変えるんだ
そこにシニカルなアーティクルか精神的原論を見出せるかどうかを試してから通報すべきだ
日本は民主主義社会だっていってたよ確か誰かが
毎日と朝日の新聞見ながら泡噴きながら

人食いてぇ=女の子監禁してぇ
人(で)食いてぇ=女の子換金してぇ
人=幼女
人=稚児
人=人

通報しますた

814 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 07:41:04 ]
お前らSTLの話しろよ。
鳥類とか哺乳類とか人間とかあんまり関係ないだろ。

815 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 09:19:26 ]
>>813
通報されないように気を付けて。

ところで、map<int,bar*> mに挿入する時、
m.insert(map<int,foo*>::value_type(0, new foo))とか
m[0]=new fooとか
するのはヤバいよね。
スマポ使えない状況でどう書くのが一番スマートですか?



816 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 10:17:56 ]
foo* p = new foo;

try
{
 m.insert(map<int,foo*>::value_type(0, p));
 // m[0] = p;
}
catch(...)
{
 delete p;
 throw;
}

817 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 10:19:22 ]
まずmap<int,bar*>のbar*を、直接 opertaor =(bar *ptr) 出来ないようなクラスに置き換える。
・map<int, test<bar> >

後はしらね。勝手に適当にメソッドでnewが隠蔽されるようなものでも書けば良いと思うよ。

818 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 11:20:34 ]
>>812
たった今>>811に食われたじゃないか


819 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 11:56:46 ]
foo* p = new foo();
if (!map.insert(std::make_pair(0, p)).second) {
 delete p;
 p = 0;
}

820 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 12:03:46 ]
p = repinterpret_cast<void*>(0);

821 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 12:18:09 ]
>>819
insertで例外起きたらメモリリークするでよ

822 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 13:35:58 ]
>>816
それだと m[0] に既存のポインタが入っていた場合にリークする。
↓これでいいかな?

foo* p = new foo;
try
{
&nbps; foo*& in = m[n];
&nbps; delete in;
&nbps; in = p;
}
catch (...)
{
&nbps; delete p;
&nbps; throw;
}

「スマポ使えない」と言ってもさすがに auto_ptr は使えるだろうから、
↓こっちのがいいと思う。

std::auto_ptr<foo> p(new foo);
foo*& in = m[n];
delete in;
in = p.release();

823 名前:822 mailto:sage [2008/07/02(水) 13:37:02 ]
うわ。 nbsp ミスった。最初のコード訂正。

foo* p = new foo;
try
{
  foo*& in = m[n];
  delete in;
  in = p;
}
catch (...)
{
  delete p;
  throw;
}

824 名前:デフォルトの名無しさん mailto:sage [2008/07/02(水) 20:34:55 ]
foo * p = new foo;
try {
std::swap(p, m[0]);
delete p;
}
catch(...) {
delete p;
throw;
}

825 名前:デフォルトの名無しさん mailto:sage [2008/07/03(木) 01:52:19 ]
関数内クラスでauto_ptrもどきを自作すればいいんじゃね?

簡単に
pair<map<int,bar*>::iterator, bool> ib(map.insert(std::make_pair(0, 0)));
if (ib.second)
  ib.first.second = new foo;
でも良い気がするけど。



826 名前:デフォルトの名無しさん mailto:sage [2008/07/05(土) 23:35:18 ]
こんばんは。g++でtr1::unordered_setを使おうと思ったのですが。
tr1::unordered_set< vector<unsigned char> >とすると
‘struct std::tr1::hash<std::vector<unsigned char, std::allocator<unsigned char> > >’
と怒られてしまいます。これは何が悪いのでしょうか?
(vector用のhash関数を自分で作る必要があるということでしょうか?)

827 名前:デフォルトの名無しさん [2008/07/05(土) 23:41:48 ]
すいませんage忘れました。

828 名前:デフォルトの名無しさん mailto:sage [2008/07/06(日) 03:22:08 ]
>>826
コードとエラーメッセージをちゃんと貼れ。

829 名前:デフォルトの名無しさん mailto:sage [2008/07/08(火) 04:21:23 ]
デバッガとかでさ、変数名長すぎでしょ。
もう嫌だ。

830 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 17:51:42 ]
#include <iostream>
#include <vector>
using namespace std;

class A {
int val;
public:
A(){cout<<"new"<<endl;}
~A(){cout<<"delete"<<endl;}
void setval(int x){ val = x; }
int getval(void){ return val; }
};

int main () {
A a;
vector<A> list;
cout <<"------------------------------------ Line1"<< endl;
for ( int i=0; i<5; ++i ) {
a.setval( i );
list.push_back( a );
}
cout <<"------------------------------------ Line2"<< endl;
//cout << "size:\t\t" << list.size() << endl;
//cout << "list[data,3]:\t" << list[data, 3] << endl;
for ( unsigned int i=0; i<list.size(); ++i ) {
cout<< list[a,i].getval() << endl;
}
cout <<"------------------------------------ Line3"<< endl;
list.clear();
cout <<"------------------------------------ Line4"<< endl;
return 0;
}

831 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 17:54:23 ]
Line1とLine2の間の
push_backのリサイズ時では何が起こっているのでしょうか

832 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 18:14:06 ]
capacityが要素を保持するのに足りなければ、メモリの再確保が起きている。

833 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 18:46:38 ]
ということは、一度破棄していると言うことでしょうか

834 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 19:57:59 ]
そのクラスAにコピーコンストラクタも書いてみ

835 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 20:48:24 ]
A(const A &obj){cout<<"copy"<<endl;} と
push_back後に1loopの目安として新しく
cout<<"----------------------------------"<<endl;
を付け足して走らせてみたところ

Line1とLine2の間の"copy"と"delete"の表示が
copy がpushした回数+1
deleteがpushした回数
になりました。

copyの回数が+1なのが気になります。
入れる側の参照+listに入っている数と考えそうになりましたが
これでサイズを比べて足りないようなら再確保…と考えるのは変よですね
copyとdeleteの順番と回数を考えると
前のvectorから入っている分コピーした回数+付け足す側からコピーの一回分
という事でしょうか



836 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 20:58:59 ]
あれ、ちょっと変ですね…3回目のプッシュで考えると
既にpushされているのが2個なので

copy  ←コピーしようとした
ここでサイズが足りないので再確保
copy  ←コピーしようとした
copy  ←前のvectorからコピー
copy  ←前のvectorからコピー
delete ←入れようとした時のテンポラリの破棄?
delete ←前のvectorに入ってるのを破棄
delete ←前のvectorに入ってるのを破棄
でしょうか、なんだか混乱してきました…。

837 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:23:27 ]
ここでサイズが足りないので再確保
copy  ←前のvectorからコピー
copy  ←前のvectorからコピー
copy  ←前のvectorからコピー
copy  ←新しい要素のコピー
delete ←前のvectorに入ってるのを破棄
delete ←前のvectorに入ってるのを破棄
delete ←前のvectorに入ってるのを破棄

だろ。まぁ新しい要素をどこでコピーするかは実装依存だろうが。
valの値も表示させれば分かるべ。

838 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:43:28 ]
それが4回目のpush_backなら納得できるのですが
3回目のpush_backでcopyが4つ表示されているので混乱しています。

839 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:49:50 ]
iが3だから3回目とか勘違いしてないか?

840 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:54:59 ]

copy
copy
delete
-----------0
copy
copy
copy
delete
delete
delete
-----------1
copy
copy
copy
copy
delete
delete
delete
-----------2

こう表示されています
環境は VC++2005EE +SDK win2000 です

841 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 21:56:29 ]
class A {
int val;
public:
A(){val=0,cout<<"new"<<endl;}
A(const A &obj){cout<<"copy"<<endl;}
~A(){cout<<"delete"<<endl;}
void setval(int x){ this->val = x; }
int getval(void){ return val; }
};


cout <<"------------------------------------ Line1"<< endl;
for ( int i=0; i<5; ++i )
{
a.setval( i );
list.push_back( a );
cout<<"----------------------------------"<< i <<endl;
}
cout <<"------------------------------------ Line2"<< endl;


ソースはこうなってます

842 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:03:30 ]
copy
----------------------------------0
copy
copy
delete
----------------------------------1
copy
copy
copy
delete
delete
----------------------------------2

うちではこうなった。
VC++2008EE

forループ入る前にvectorになんか入れてない?
size()の値表示させてみ。

843 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:06:00 ]
これが全文です。
#include <iostream>
#include <vector>
using namespace std;
class A {
int val;
public:
A(){val=0,cout<<"new"<<endl;}
A(const A &obj){cout<<"copy"<<endl;}
~A(){cout<<"delete"<<endl;}
void setval(int x){ this->val = x; }
int getval(void){ return val; }
};

int main (){
A a;
vector<A> list;
cout <<"------------------------------------ Line1"<< endl;
for ( int i=0; i<5; ++i ){
a.setval( i );
list.push_back( a );
cout<<"----------------------------------"<< i <<endl;
}
cout <<"------------------------------------ Line2"<< endl;
for ( unsigned int i=0; i<list.size(); ++i ) {
cout<< list[a,i].getval() << endl;
}
cout <<"------------------------------------ Line3"<< endl;
list.clear();
cout <<"------------------------------------ Line4"<< endl;
return 0;
}

844 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:36:38 ]
2005入れてないから2003でやってみたらそうなった。
ソース追ってみると、追加する要素を一旦ローカル変数にコピーしてた。
その変数のコピーと破棄が1回ずつ多いみたい。
2005のソースはわからんが多分同じ理由だろう。

845 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 22:41:38 ]
なるほど、これで胸のつかえが取れました
付き合ってくれた皆さん、本当にありがとうございました。



846 名前:デフォルトの名無しさん mailto:sage [2008/07/09(水) 23:04:39 ]
>>844
>追加する要素を一旦ローカル変数にコピーしてた。

list.push_back( list[3] );






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<192KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef