1 名前:858 [2007/12/24(月) 03:41:59 ] C++標準ライブラリの一つ、STLについて。 前スレ 【C++】STL(Standard Template Library)相談室 7 pc11.2ch.net/test/read.cgi/tech/1185986999/ 過去ログ・リンク・書籍紹介は >>2 以降
809 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:20:42 ] 答になってないぞ。 >>745 に書いてあるのは「取得したあとにやりたいこと」。 質問は「どんな手段で取得した直後を想定しているのか」だ。
810 名前:803 mailto:sage [2008/02/20(水) 11:30:31 ] >>809 ですから、 vector::insertするためにはイテレーターが要りますよね? で、item[6] としてイテレーターを取得したときに、そのイテレーターは有効なのか無効なのか、という判定。
811 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:51:08 ] >>810 イテレータを取得する前に検査すべき。 例えば、std::vector<int> foo(5); std::vector<int>::iterator it = foo + 6;の結果は鼻から悪魔。
812 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:54:57 ] >>810 item[6] ではイテレータを取得できないと思うよ item.begin() + 6 のことか? itemの6番目の要素が存在するなら、当然有効だし、 存在しないなら、何が返ってこようかくるまいが item.begin() + 6 を実行した時点でアウト
813 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:58:27 ] >>810 よくわからんが、こういうことか? void foo(vector<int>& v, int index) { vector::iterator iter = v.begin() + index; // この iter は有効か判断したい. v.insert(iter, 5); } ならば、こう書けば良い void foo1(vector<int>& v, int index) { if (v.size() < index) v.resize(index); // iterが必ず有効になるように、事前にvectorを拡大する. vector::iterator iter = v.begin() + index; v.insert(iter, 5); } void foo2(vector<int>& v, int index) { if (v.size() < index) throw std::invalid_argument("index が大き杉"); // 範囲外なら例外を投げる. vector::iterator iter = v.begin() + index; v.insert(iter, 5); }
814 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:15:16 ] 作った直後で無効なイテレータってあるのか? 作ること自体が違法だったり、作った後に無効になったりするのなら分かるんだが・
815 名前:810 mailto:sage [2008/02/20(水) 12:20:17 ] >>813 やりたいことは、 ある行の後に1行追加したい、 だから、foo1でできるのはできます。 でも、ある行の後に1行追加するメソッドくらい、std::vectorとかが標準で持ってて欲しいと思うお。
816 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:33:35 ] >>815 却下だな。 - 勝手に resize() するなら、途中の要素を何で埋めるか指定しないといけない。 - 挿入位置は iterator で指定するのが標準コンテナの流儀なのに、この場合だけ インデックスで指定するのはおかしい。 - vector のメンバにしてもユーザーが実装しても効率などは変わらない。 標準で持っていたほうがいい理由が何も思いつかない。
817 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:35:35 ] >>814 作った直後のイテレータは、コンテナの中身を指しているか、end()と等値か、だよな。 だからこっちは「本当に作った直後なら、!= vector.end()との比較でいい」って言ってるのに、 この質問者、「自分の訊きたいこと」と「自分の訊いていること」を一致させられないんだよ。
818 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:57:08 ] おまえら頑張ってるが、実行効率も考えろ。 結果的に再取得したほうが良かったりして。
819 名前:786 mailto:sage [2008/02/20(水) 13:51:57 ] いろいろ勘違いしていました。 実際はイテレータじゃなくてただのインデックスでした。 0<=index<vec.size() で十分でした。 イテレータの場合は持ってる間vectorを変更しないようにしています。
820 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 13:53:28 ] エエェェェ
821 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 14:18:16 ] >>819 う゛ーう゛ー
822 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 14:20:36 ] これは酷い釣りだ…
823 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 16:22:14 ] 結論としてイテレーターは役立たずでOk?
824 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 16:30:10 ] list をイテレータなしでというのはちょっと vector にはいらないけどさ
825 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 16:37:03 ] listの返したイテレータが無効になるタイミングって、 list本体が破棄された場合と、イテレータ先がeraseされた 時だけでしょうか?
826 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 16:46:18 ] 元からC++にあった下位概念(ポインタ)が要求するメモリ構造を持っているvectorは、 後から加わった上位概念(イテレータ)を使わずとも、下位概念のやり方で各要素を見ていける、 だから「必須ではない」・・・という意味では、無くてもいいかもね。 実際には、stringやlistがbegin() end()してる中、vectorだけ&vec[0]とか使ってポインタでいじるのは えらく不自然だから、vectorもイテレータで扱ってしまうけれども。
827 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 18:04:53 ] >>825 合ってる(要素を消す関数はerase()以外にもあるけど)。あと標準には list1.splice(list2); するとlist2へのイテレータが全部無効になる、と書いてあるけど、 実際にはほぼ間違いなくlist1への有効なイテレータになる。 これは標準の方が訂正される可能性が高い。
828 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 19:40:59 ] >>827 返答ありがとうございます。 listに要素追加したときイテレータを保存しておいて、 それを別なコンテナでインデックス化するってな使い方を しても大丈夫そうですね。 spliceの >実際にはほぼ間違いなく ってところはちと怖いので、使用は避けときます。
829 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:01:56 ] >>827 最新のドラフトだと 「移動した要素を指し続ける」 と書いてあるね。
830 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:36:58 ] 250. splicing invalidates iterators Section: 23.2.3.4 [list.ops] Status: WP Submitter: Brian Parker Date: 2000-07-14 void splice(iterator position, list<T, Allocator>& x); invalidates all iterators and references to list x. This is unnecessary and defeats an important feature of splice. In fact, the SGI STL guarantees that iterators to x remain valid after splice. WPってWorking Paperってなってるけど一度却下されてるんだよね。 で、最新のドラフトだとC++0xで修正されることは決定? WP The proposed resolution has not been accepted as a Technical Corrigendum, but the full WG21 committee has voted to apply the Defect Report's Proposed Resolution to the working paper.
831 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:44:24 ] N2461 だと次のように書いてある。 23.2.3.4 list operations void splice(const_iterator position, list<T, Allocator>&& x); 4 Effects: Inserts the contents of x before position and x becomes empty. Pointers and references to the moved elements of x now refer to those same elements but as members of *this. Iterators referring to the moved elements will continue to refer to their elements, ← ここ but they now behave as iterators into *this, not into x.
832 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:49:02 ] moveの導入による影響おそるべし
833 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:53:24 ] >>831 Working Draftか。 そうなりそうだね。
834 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:02:47 ] >>832 list の splice は,標準ライブラリへの move の本格導入以前から, auto_ptr と並ぶ標準ライブラリにおける move の代名詞だったような? 現行の規格が不必要に制限が強すぎた (iterator の stability を保証しなかった) だけで, move 導入とは直接関係ないんじゃないですかね? >>831 の splice の第2引数が右辺値参照型に変更されたのも 単に一時変数を渡すことができるようにしただけでしょうし.
835 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:05:17 ] rvalue reference うぜえな。。 基本仕様としては これが一番インパクトでかいかな。
836 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:07:39 ] concept 周りが間に合えばあれも相当インパクト大きいのでは
837 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:07:54 ] 今まで const Widget operator+(Widget, Widget) とかしてたものが Widget&& operator+(Widget, Widget) になるのか。
838 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:08:37 ] テンポラリオブジェクトを渡せるようになるのはいいのだが、 そのせいで左辺値参照でいい状況でもムーブが発生するのが微妙だな。
839 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:26:14 ] 以下は C++0x を前提にしたレスです.スレ違いですいません. >>837 Widget の実装と operator+ の機能によりますけれど 値で返すのと参照で返すのでは基本的に意味が違ってしまうのでは? で, move の恩恵を受けたければ Widget を move 可能にした上で Widget operator+(Widget, Widget) となるのが一般的かと思います. >>838 >そのせいで左辺値参照でいい状況でもムーブが発生するのが微妙だな。 その微妙になる具体例ってどんなのがありますかね?
840 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:37:12 ] l1.splice(it, l2); 右辺値参照の場合 1. l2 -> x のムーブ 2. x のノードを l1 に付け替える 左辺値参照の場合 1. l2 のノードを l1 に付け替える
841 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:42:46 ] >>839 戻り値をWidgetにしてしまうと代入できてしまうので constをつけてるんだけど、 @const Widget operator+(const Widget&, const Widget&); AWidget&& operator+(const Widget&, const Widget&); 現在は@のようにしてるけど、C++0xからはAでいいかなと思った。 どちらも Widget w1, w2, w3; if( (w1 = w2) = w3 ) のようなケアレスミスをコンパイルエラーにしてくれると思ったけど、 Aだと (w1 = w2) = w3 はOKになってしまうか。右辺値参照に左辺値 は代入できるか。
842 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:44:44 ] const Widget operator+(const Widget&, const Widget&); と書いた場合、const Widget はムーブできるのか?
843 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:44:56 ] >839 >838 じゃないけど。 値渡しにした段階でコピーが発生しちゃうから、 Widget&& operator+(Widget&&, Widget&&); Widget&& operator+(Widget&&, const Widget&); Widget&& operator+(const Widget&, Widget&&); Widget operator+(const Widget&, const Widget&); 頑張るんならこうなるんじゃないの? std::string の operator+() はこうなってるが。 あと、微妙ってのは左辺値参照なら単純にアドレス渡すだけで済んだものが、ムーブ処理が発生しちゃうのが嫌ってことなんじゃないかと。 で、↑はそのためにオーバーロードしてるけど。
844 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:46:52 ] >>840 引数のl2は右辺値という前提だよね。そうするとmoveの分だけ効率が 悪くなるということかな。
845 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:51:32 ] >>842 ん?メイヤーズの本で推奨されてたから従ってる。 >>843 ドラフト見たところでは、例えば Widget&& operator+(Widget&& lhs, const Widget&& rhs); の場合、両方の実引数にWidgetの一時オブジェクトを 渡すとlhsとrhsは右辺値になって、両方に左辺値を渡すとlhsとrhsは 左辺値になるという理解でいい?
846 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:55:53 ] >>840 現行の list の splice の意味からすると, splice という名前に前者の操作を overload させると混乱するのでは? 前者は最新の working draft に従えば,例えば l1.splice(it,decltype(l2)(move_iterator(l2.begin()),move_iterator(l2.end()))); と書けると思いますけれど,これではダメなのですか? あと,「左辺値参照の場合……」「右辺値参照の場合……」という書き方を されていますけれど, l2 の型が右辺値参照型か左辺値参照型か,ということですか? もしそうだとすると,l2 はそのままでは常に左辺値として扱われるので, void splice(iterator, list<T,A>&); と void splice(iterator, list<T,A>&&); があった場合には, l2 が右辺値参照型か左辺値参照型かに関わらず 常に前者が呼ばれると思います.
847 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:00:25 ] しかし void splice iterator, list<T,A>&); は存在しない
848 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:03:20 ] >>841 一時オブジェクトに対するメンバ関数呼び出しの overload は 右辺値参照型の *this への拡張が対応するかと思います. www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm 例えば,右辺値に対して Widget::operator=(const Widget&) を禁止したければ class Widget{ Widget& operator=(const Widget&) & { ... } Widget& operator=(const Widget&) && = delete; ... } 上記のようになるかと思います.従って Effective C++ にある>>845 の記述は C++0x では deprecated になるかと思います.
849 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:06:33 ] >>842 move はそのソース (move 元) に対して破壊的操作を行うことになるので 戻り値に対して const を指定しているとその戻り値に対して move を行うことはできなくなると思います. Widget& Widget::operator=(const Wideget&); // copy assignment と Widget& Widget::operator=(Wideget&&&); // move assignment があった場合,>>842 の operator+ の戻り値に対しては オーバーロードの優先順位を解決した結果, copy assignment が呼ばれるかと.
850 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:06:55 ] dequeとvectorの速さ比べをしてみた(gcc 3.4.5 mingw) for(i=0; i < num; i++){ foo += v[i]; } みたいなの。 vectorの先頭をポインタに渡してポインタ経由でアクセス >>>>>>vectorを[]でアクセス>>>vector をiteratorでアクセス=dequeをiteratorでアクセス >>>>>>>(越えられない壁)>>>>>>dequeを[]でアクセス dequeがあればvectorはいらない子みたいなカキコがあったけど、やっぱvectorはやればデキる子だよ。
851 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:15:29 ] >>843 ありがとうございます.微妙な具体例が理解できました. これを気にするならば overload 頑張るしかないですね.
852 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:18:07 ] オーバーロードで解決は出来るけど、 沢山あると大変だね。
853 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:27:12 ] 蛇足ですけれど,>>843 は書かれているような「微妙な状況」の他に, 引数が一時オブジェクトで,その一時オブジェクトのバッファが 結合後の文字列を保持できる余裕がある場合に, バッファの再確保を回避できる最適化を積極的に活用できる というのもあるかと思います.
854 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:34:05 ] >>847 元々 splice は move (破壊的コピー) を行うという意味づけであり 右辺値と左辺値を区別する必要はなく, void splice(iterator, list<T,A>&); と void splice(iterator, list<T,A>&&); をオーバーロードする必要もないと自分は思います (し,おっしゃるとおり working draft も今のところそうなっています)
855 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:35:07 ] >>850 vectorアクセスするのにiterator経由より[]の方が速いって謎すぎる。 何らかの理由で最適化に失敗してるか、assertが効いてるんじゃ?
856 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:48:29 ] >>855 最適化オプション何もなしだお
857 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:49:40 ] >>855 ちなみに、倍速くらい ポインタにすると[]のさらに倍 ちなみにdequeの[]はvectorの[]の4倍遅い
858 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:50:03 ] -O2つけて測定コード毎最適化で消してしまえ。
859 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:50:18 ] あほすぎ。
860 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:54:00 ] ふつーSTLは最適化かけて実測するもんだと思ってたのだが、違うのか?
861 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:57:15 ] STL に限らず、実測は最適化かけてからやるのが普通。 最適化しない場合の影響を調べるのでもない限りは。
862 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:05:39 ] ふつー、最適化をかけるとvetor::operator[]はポインタアクセスと同じコードに 展開される。実際、gcc3.4.6 -O2ではそう。
863 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:24:53 ] dequeのメモリ構造は複数のメモリブロックから成っているので ブロック間でindirect accessが発生するから、要素へのアクセス とiteratorの操作はvectorより遅くなるというのが一般論。
864 名前:デフォルトの名無しさん [2008/02/21(木) 00:35:31 ] >>854 ほほう。結局、 void splice(iterator pos, list<T,A>&& l2); この場合、l2に右辺値(一時オブジェクト)を渡そうが 左辺値を渡そうが、l2は常に左辺値として扱われるという ことだよね?この仕様変更のメリットとしては、右辺値も 渡せるということかね。
865 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:47:02 ] >>864 splice の定義内では,明示的にキャストをかけるか std::move を使うかしないと l2 は左辺値として扱われると思います. >この仕様変更のメリットとしては、右辺値も渡せるということかね。 自分はそう理解していたので>>834 のように書きました. 右辺値が渡せるので>>846 に書いたような l1.splice(it,decltype(l2)(move_iterator(l2.begin()),move_iterator(l2.end()))); みたいなコードも通るようになります.
866 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:50:32 ] >>865 後半は漏れの理解不足で分からんけど、アリガトン。
867 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:55:32 ] >>866 すいません. l1.splice(it,list<int>(l2.begin(),l2.end())); みたいなコードも通るようになるといいたかったんです. といいますか>>846 のとかこれの場合は insert で良いですね……orz
868 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 01:37:08 ] >>867 いえいえ。 move_iteratorとか見たことなかったので漏れの理解不足というより 知識不足だった。範囲指定のコンストラクタで一時オブジェクト をそのまま渡すことができると。 それが、l1.insert(it, l2.begin(), l2.end());で可能だったという こっですね。
869 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 10:09:34 ] >>813 >vector::iterator iter = v.begin() + index; やっぱ、イテレーターとるときってbegin()で取るのが正しいのか。 >vector::iterator iter = &v[index]; ってのはダメ? ってか、おk、だったとしてもvectorとdequeでしか通用しないBADな書き方?
870 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 10:21:31 ] それはポインタ。 全てのSTL実装でコンパイルが通る保証はない。
871 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 10:27:49 ] サンクス。 つまり、書き方という問題じゃなくて、使ってるSTLの実装上たまたまコンパイルエラーが出ないだけなんだね。 すげー賢くなったお( ^ω^)
872 名前:871 mailto:sage [2008/02/21(木) 10:30:40 ] あっ、本当だ。vectorをdequeに変えたらコンパイルエラー。 実行時エラーじゃなくて、コンパイルエラーなのは好感( ^ω^)
873 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 12:52:05 ] 散々既出だけど、vectorの場合は、int* p = &v[index];も可能。 ただ、end相当の&v[v.size()]は未定義だから、&v[0] + v.size()を使えって話があった気もする。
874 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 12:58:44 ] いいえ。
875 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 13:01:28 ] >int* p = &v[index]; これはvectorに限らずあらゆるコンテナで可能だろ
876 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 13:08:38 ] そうですね。
877 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 13:09:09 ] え”? dequeでコンパイルエラー出たけど、気のせい? もうテストコード消しちゃったお。
878 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 13:11:06 ] >>875 釣りですか?
879 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 13:17:54 ] いいえ。
880 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 13:37:04 ] 不正確な物言いだったな operator[]を持っていて、value_typeがintであるような、あらゆるコンテナのインスタンスについて可能、と言いたかった
881 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 13:55:22 ] それはうっかりだった、すまん。 vectorのポインタの場合は、配列の要素を指すポインタの如く、 ポインタ演算を使用してそのvectorインスタンスの保持する他の要素も参照できると言えばいいか。
882 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 13:58:46 ] std::stringは、イテレータンを無視して、何文字目かを数字で指定しても、おkだおね?
883 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 14:03:08 ] >ただ、end相当の&v[v.size()]は未定義だから、&v[0] + v.size()を使えって話があった気もする。 で、これは?
884 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 15:09:32 ] &v[0]の時点でただのポインタなんだから、それにどんな値を足しても 指してる先にアクセスしなきゃ大丈夫でしょ。
885 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 15:30:22 ] 配列の最後の要素の一つ後の要素のアドレスをポインタ演算に 使用することは規格で認められていた記憶がある。 これが正しければ &v[v.size()] は有効だと思う。
886 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 15:30:54 ] >>884 ダウト。
887 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 15:31:47 ] stringのuppercaseはどう書きますか?
888 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 15:56:50 ] >>885 その式は右から評価するからアウト
889 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 16:01:43 ] >>885 vectorのoperator []は多重定義された関数なのだから、それとは別に規定があるはず。 と思ってX 3014見てみたが、23.1.1 列の中で参照されている表68に a[n]は*(a.begin() + n)と書かれているがそれ以上は何もない。 もちろん、atはn >= a.size()のときにout_of_rangeを送出と書いてあるけど。
890 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 16:23:53 ] >>885 v[v.size()]の時点で鼻から悪魔確定だろ
891 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 16:27:30 ] >>890 なんで?
892 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 16:29:38 ] >>886 なんで?
893 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 16:36:28 ] >>889 a.begin() + n は dereferenceable ではないので これを dereference した時点で規格としては undefined behavior, でよいのでは?
894 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 16:48:51 ] std::string に trim が無いなんて不自由でつね。
895 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 16:51:25 ] まぁ、色々足りないものはある。
896 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 17:25:46 ] >>888 No アドレス演算子&はオペランドが[ ]演算子の結果の場合、単項&演算子と [ ]演算子が暗黙に意味する単項*演算子は評価されず、&演算子を削除し [ ]演算子を+演算子に変更した場合と同じ結果となる。 つまり、&v[v.size()] は v + v.size() に評価されるのであって、 &(*(v + v.size)) とは評価されない。
897 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 17:27:38 ] >>888 C言語もあまり詳しくないだろ?K&Rにも、>>885 が正しいことは書いてある。 かつ、C++でも同じ。
898 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 17:44:24 ] >>896 それはポインタについてじゃないのか >>889 も言ってるが、vectorの[]や、vectorのイテレータの+と*は単なる関数かもしれない訳で、 ポインタについての規定がそのままあてはまるとする理由はないだろ
899 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 18:01:34 ] stringの数字チェックはできますか?
900 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 18:47:36 ] >>898 そのとおりだ。ポインタの話しと思ってた。
901 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 18:52:15 ] &v[0] + v.size()でOK
902 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 22:31:04 ] 私はヘタレなのでそんなに悩んでる暇があったらイタレータ使っちゃいます ごめんなさい
903 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 22:33:11 ] >>902 僕もです。
904 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 23:01:29 ] サイズが0のときの&v[0]は不定だ。VS2005だとアサート。
905 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 00:39:14 ] おかしなコード書きすぎ><
906 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 08:41:26 ] 結局STLって無いと困るけど、書き難いね。 複数ファイルイメージみたいなのをバッファに持っておきたいばあいは、 みなさんどうされてます? void*?char*? やっぱ、vector <char*>みたいな感じ?
907 名前:906 mailto:sage [2008/02/22(金) 08:54:20 ] *で宣言しちゃうと、メモリの開放を書かないと逝けないから、 vector <string>の方が良いかなぁ?
908 名前:906 [2008/02/22(金) 09:30:49 ] たまには質問にも応えて欲しいお。
909 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 10:05:33 ] >>906 テキストファイルである保証があるなら兎も角、普通はvector<string>はつかわんだろ。 つーか、ファイルの内容によって違うものを一般化されても困る。