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


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

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



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>はつかわんだろ。
つーか、ファイルの内容によって違うものを一般化されても困る。

910 名前:906 mailto:sage [2008/02/22(金) 10:06:37 ]
テキストファイルじゃなくてバイナリファイルです。

TMemoryStremaみたいなのが欲しいんです。

911 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 10:08:23 ]
ファイルをvector<char>に入れるとして、複数ファイルならvector<vector<char> >でいいんでね?
なにをやりたいか判ればもっと適当な方法もあるかもしれないけど。

912 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 10:08:31 ]
>>906 vector<char> じゃないのか?

913 名前:906 mailto:sage [2008/02/22(金) 10:27:17 ]
>vector<vector<char> >

おk。
ファイルのロードとか要りますよね。
出来上がったクラスが標準だったり、ネットに転がってて欲しい。

914 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 10:40:03 ]
クラス? 何を言ってるんだ? このスレがなんだか判っているか?
STLの使い方を提示されたんだから、後は自分で勝手に実装すればいいだろ。

915 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 10:46:03 ]
だって普段STL使ってる人たちが、便利な標準クラス使ってるか自作クラスライブラリそろえてるに決まってるじゃん。

916 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 10:55:17 ]
もうかまうなよ。

917 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 11:00:59 ]
>>913
あのさ、先日からC++BuilderのVCLを移したいみたいだけどさ
STLはVCLと範疇が違うんだから、ファイルロードだのなんだのは
自分でやってくれるかな。



918 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 13:53:18 ]
じゃ、せめて、

>vector<vector<char> >

をカプセル化した便利なクラスだけでも教えてorz

919 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 13:54:32 ]
そんなものないよ

920 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 13:57:18 ]
そういえば、copiedはともかくfile_rangeくらいBoostにあってもいいのにって思う。
namespace oven = pstade::oven;
std::size_t n;

std::vector<std::vector<char> > v;
v.reserve(n);

for (std::size_t i = 0; i < n; ++i)
{
std::ifstream is(...);
v.push_back(oven::file_range<char>(...) | oven::copied);
}

921 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 14:00:54 ]
どう見てもifstreamの行は消し忘れです、本当に(ry。

922 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 14:56:03 ]
string::compareはありますが、大文字小文字を無視してcompareする場合は、皆さんどうされてるのでしょうか?


923 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:03:55 ]
stricmp

924 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:06:51 ]
文字列まわりはSTLに期待すんな、クソだ

925 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:12:43 ]
そーなんですか。

構造体まわりはSTLで完璧ですが。

で、文字列まわりは何使えば良いですか?
ってstringしか無いじゃん。
あー、ハイパーなstringのソース落ちてないかなぁ。

926 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:17:24 ]
構造体てw

927 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:18:47 ]
あ、structもclassも等価らしいですが、
何もしないデータの塊にはstruct使ってます。

変ですか?



928 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:21:17 ]
>stricmp

試してみましたが、やっぱ、.c_str() 付けないとコンパイル通りませんね。
これくらい標準にして欲しいお。

929 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:36:00 ]
春だなぁ

930 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:42:26 ]
まだ冬ですよ

931 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 15:57:45 ]
これがvipクオリティ

932 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 16:13:44 ]
ファイルや文字列処理は微妙にスレ違いな気もするなぁ。
boostでよければboost.string_algoに色々あるしSTLにこだわる必要はないだろ。
boost.string_algoなら>>922はboost::algorithm::ilexicographical_compare。

ところでstricmp/strcmpiって標準だっけ?

933 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 16:49:51 ]
std::string って、
==
で比較できましたっけ?

934 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 16:55:53 ]
できる

935 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 17:53:15 ]
>>932
stricmpもstrcmpiもstrcasecmpも標準Cには存在しない。
最近のPOSIXにはstrcasecmpがあるけど、locale依存なので
画面に表示する文字列をソートするくらいしか使い道がない。

936 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 18:08:08 ]
>>935
なるほど。d

937 名前:デフォルトの名無しさん mailto:sage [2008/02/22(金) 20:58:33 ]
一瞬、初心者歓迎スレきたのかと思ったぜw



938 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 00:16:23 ]
似たようなもんかもw

939 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 00:18:06 ]
string って STL に含まれるの?

940 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 00:50:55 ]
ど  っ  ち  で  も  い  い

強いて言うならC++標準。
つまんないことにこだわらんでも良いよ。

941 名前:デフォルトの名無しさん mailto:sage [2008/02/23(土) 00:51:02 ]
頻出ネタの上に面白くない議論にしかならないのでスルー

942 名前:デフォルトの名無しさん [2008/02/24(日) 11:20:20 ]
std::map<int, std::string> string_map;
assert(string_map[1].empry());
assert(string_map[100].empry());
assert(string_map.size() == 2);

つまり、存在しないキーを operator[] で指定すると
そのキーが自動的に挿入されて値はデフォルトコンストラクタ
で作成されてしまうということですか?
うむむ、例外になってくれればいいのだが。

std::vector でも operator[] は例外を出さないから
それに対応した動作ということなんでしょうか?

943 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 11:45:26 ]
単に
string_map[1] = "foo";
ってやったときに存在しないキーを指定すると自動的に追加されてほしいからじゃね?

944 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 11:53:02 ]
そうそう
存在するかどうかも含めて問い合わせるにはfindを使う

945 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 13:17:17 ]
>>942
次の規格の改訂では、存在しないキーに対して例外を投げる at() が追加されるよ。

946 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 13:58:04 ]
統一性のある素晴らしい改訂ですな。

947 名前:デフォルトの名無しさん [2008/02/24(日) 14:42:27 ]
まぁ copy_if の一軒もあるしな



948 名前:デフォルトの名無しさん [2008/02/24(日) 14:42:47 ]
for_each_if とかもほしい

949 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 14:43:47 ]
なんで標準にcopy_ifがないんだって話?

950 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 14:47:46 ]
vector に data が追加されたり、
何で無かったんだ? って機能が色々追加されてるみたいだね。

951 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 14:48:12 ]
そういえば規格の改訂で copy_if() が追加されないのはなぜなんだぜ?

952 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 14:54:32 ]
最新ドラフト(これ、最終ドラフトだっけ?)にも載ってないな。

953 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 14:55:44 ]
今公開されてる最新は n2521.pdf のはず。無いな。

954 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 14:57:21 ]
禿が10年越しの天丼ねらってる、とか?

955 名前:デフォルトの名無しさん [2008/02/24(日) 14:59:55 ]
質問失礼します。。
struct ST{
  int n;
};
vector<ST> v;
set<ST> s;

int main(){
  ST x={0};

  v.push_back(x);
  vector<ST>::iterator itv=v.begin();
  itv->n++;

  s.insert(x);
  set<ST>::iterator its=s.begin();
  its->n++;
}
のようにすると、its->n++;の行で
error: increment of data-member ‘ST::n’ in read-only structure
と出るのですがvectorで出来てsetで出来ないのはなぜでしょうか?

956 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 15:03:57 ]
今すぐsetのイテレータタグを調べるんだ


957 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 15:04:24 ]
ごめんnの方だったのね



958 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 15:04:44 ]
>>955
set は常にソートされた並びを保っている必要があるから。

959 名前:955 mailto:sage [2008/02/24(日) 15:17:04 ]
>>956-958さん
iterator経由で勝手に中身を変えられたら困るということは、
setとmapだけの例外扱いなのですか?
イテレータタグというのは初見なのでちょっと調べてみます。

960 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 15:28:50 ]
map は second の方は変えれる。

961 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 15:28:54 ]
>>959
map の場合は value_type である pair の first がソートキーなので、これは
書き換えられないように const が付いてる。 second は順序に関係ないので
書き換えてもいい。

962 名前:955 mailto:sage [2008/02/24(日) 15:31:13 ]
>>960,961さん
なるほど、そうなっているのですね。
よく分かりました、どうもありがとうございました。

963 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 15:43:02 ]
compareが感知しないメンバなら、mutable付けていじることはできるけどね。

964 名前:デフォルトの名無しさん mailto:sage [2008/02/24(日) 16:01:24 ]
まぁそれは奥の手ということでw

965 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 14:04:12 ]
ファイルに簡単に新規作成、追記ができる方法ありますか?

ofstreamって、bad()とかfail()とか使いにくい。

966 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 14:18:47 ]
ofstream.exceptions(badbit | failbit);
ってやっとけばいちいちチェックしなくても例外吐いてくれると思う
それが使いやすいかどうかはわからんが…

967 名前:965 mailto:sage [2008/02/25(月) 14:25:43 ]
サンクス>>966



968 名前:デフォルトの名無しさん [2008/02/25(月) 16:54:00 ]
そんな機能があったとは

969 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:08:09 ]
そういえばostreamのfail()が真になる事ってあるの?

970 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:24:02 ]
>>920
>file_range

ずっと見てても分からないんですが、file_rangeって何ですか?

971 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:29:12 ]
ファイルの先頭から末尾の一つ後ろまでを指すイテレータのペアみたいなもん

972 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 17:30:41 ]
使い方キボン

973 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 18:12:11 ]
複数のファイルがあって、それがローデータだったり、テーブルデータだったりします。

複数のファイルを混在させずに簡単にロードしてしまうクラスが欲しいのですが、どんな実装になりますか?

974 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 18:13:10 ]
>>972
コンストラクタで開いたら後はただのRange。
p-stade.svn.sourceforge.net/viewvc/p-stade/trunk/pstade/libs/oven/test/file_range.cpp?revision=1481&view=markup
p-stade.sourceforge.net/oven/doc/html/oven/ranges.html#oven.ranges.file_range

Range自体はここでも見て。
www.kmonos.net/alang/boost/classes/range.html

975 名前:デフォルトの名無しさん mailto:sage [2008/02/25(月) 18:16:01 ]
さんks>>974

boostなんですね。STLに昇格するまで待ってようかなぁ。
ちょっと気後れしてしまうorz


976 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 08:54:04 ]
973もヨロ!

977 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 08:59:15 ]
>>973
ローデータ、テーブルデータ、ファイルを混在、簡単に、ロード
これだけ曖昧な言葉を並んでるとさすがに意味がわからん。



978 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 11:28:42 ]
いや、だからメモリにロードしたいけど、
ファイルの種類が増えるたび書き換えするのは面倒なので、
ポケットみたいにどんどんファイル(ファイル名)を入れていくとその中でメモリになってる、みたいな。

979 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 12:01:54 ]
>>978
// ちょっとエスパーにチャレンジしてみたい気分になった
// こうですか?
#include <vector>
#include <map>
#include <string>
#include <istream>
#include <iterator>
#include <fstream>
#include <cstddef>
#include <exception>
#include <iostream>
typedef std::vector<char> memory_type;
class pocket {
std::map<std::string, memory_type> naka;
public:
void ireru(std::string const& filename) {
std::ifstream file(filename.c_str());
file.exceptions(std::ios::badbit | std::ios::failbit);
naka[filename].assign(std::istreambuf_iterator<char>(file)
, std::istreambuf_iterator<char>());
}
};
int main(int argc, char* argv[]) {
try {
pocket pocket;
for (int i = 1; i < argc; ++i) { pocket.ireru(argv[i]); }
return EXIT_SUCCESS;
}
catch (std::exception const& e) { std::cerr << e.what() << std::endl; return EXIT_FAILURE; }
}

980 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 12:18:03 ]
乞食は消えろ

981 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 12:25:50 ]
さて埋めるか。

982 名前:978 mailto:sage [2008/02/26(火) 12:58:13 ]
サンks>>979

そのまま使ってみます。
でも、ireruメソッドはメソッド名変えるけど。

class pocketもclass memoryPocketの方が良いかなぁ?


983 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 14:12:22 ]
978がアホすぎて吹いた

984 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 14:15:27 ]
吹いても良いから、自分はどーゆーふーに作ってるか書けお。

985 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 14:24:08 ]
スレタイに「初心者」か「宿題」が付いてるスレへ行ってくれ。
マジで邪魔。

986 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 14:29:55 ]
>985
おま、ふよー

987 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 15:16:46 ]
>>985
おまえだって大したことはないだろ



988 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 16:42:30 ]
次スレマダー?

989 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 18:44:25 ]
邪魔っていうか、ゴミだよね。
なんでこのスレ見てるんだろう。

990 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 19:03:06 ]
リアルで同じ事言われてここに辿り着いたんだろう

991 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 20:47:50 ]
ジエンオツ

992 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 21:41:38 ]
ということにしておこうか:-)

993 名前:デフォルトの名無しさん mailto:sage [2008/02/26(火) 23:55:52 ]
次スレ
pc11.2ch.net/test/read.cgi/tech/1200044614/

994 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 01:16:16 ]
あれ?あ、そういうこと・・・

995 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 01:17:38 ]
STLスレはいらんという事?

996 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 01:25:47 ]
まぁ毎度のことだな。
こっちが二ヶ月で 1000 。
あっちが一月半で 800 。
あわせると、だいたい一月でちょうど 1000 か。

997 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 02:03:52 ]
【C++】STL(Standard Template Library)相談室 9
pc11.2ch.net/test/read.cgi/tech/1204045410/



998 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 02:04:35 ]
【C++】STL(Standard Template Library)相談室 7
pc11.2ch.net/test/read.cgi/tech/1185986999/
【C++】STL(Standard Template Library)相談室 6
pc11.2ch.net/test/read.cgi/tech/1160821240/
【C++】STL(Standard Template Library)相談室 5
pc8.2ch.net/test/read.cgi/tech/1143608073/
【C++】STL(Standard Template Library)相談室 ;4
pc8.2ch.net/test/read.cgi/tech/1130680264/
【C++】STL(Standard Template Library)相談室 3
pc8.2ch.net/test/read.cgi/tech/1116559700/
【C++】STL(Standard Template Library)相談室 2
pc8.2ch.net/test/read.cgi/tech/1104898734/
【C++】STL(Standard Template Library)相談室
pc5.2ch.net/test/read.cgi/tech/1095583235/

999 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 02:07:03 ]
新スレからの誤爆とは珍しい。

1000 名前:デフォルトの名無しさん mailto:sage [2008/02/27(水) 02:08:40 ]
次すれ
pc11.2ch.net/test/read.cgi/tech/1204045410/

1001 名前:1001 [Over 1000 Thread]
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。






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

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

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