【C++】STL(Standard Template Library)相談室 7
6 :
デフォルトの名無しさん :2007/08/02(木) 02:15:51
とりあえず立てときました。 ////////////////////////////////////////////////////////// // 更新履歴 // // [テンプレに関して] // // 2007/08/02 // ・リンク切れのページがあった為、そのリンクを外しました。 // ・書籍、amazonのリンクが長すぎる為、短く変更しました。 // //////////////////////////////////////////////////////////
結局立てちゃったのね
定期的にboostや0xの話題出して統合を促すしかないようだな お前らも協力しろよ
>>8 準標準のboostと標準のSTLのスレを統合するのはどうかと思う。
主観やけど難易度としては boost > STL だと思ってるから、
統合したら、STL入門者の居るスレで、boostの新コンポーネントの話はし辛い。
今までどおり、
「std::auto_ptr満足できねー」
「つ boost::shared_ptr」
って流れでいいかと。
0x専用のスレは・・・無くても・・・いいかな。
とりあえず貼っとく。
http://pc8.2ch.net/test/read.cgi/tech/1104898734/562 562 名前:デフォルトの名無しさん[sage] 投稿日:2005/05/05(木) 02:58:39
"STL"なんて呼称の範囲は、C++の標準ライブラリに
取り込まれてしまった今となっては明確に区切れる物では無い。
HP STL や SGI STL のことを指して言ってるのかもしれないが、
今使われてるのはそれらをベースにしたC++標準ライブラリだ。
範囲が明確に決まってるかのように、含まれるだの含まれないだの言うのは時代遅れだぞ。
このスレが不要である事に疑いの余地は無い。
11 :
デフォルトの名無しさん :2007/08/02(木) 05:45:07
お前が勝手に考えた基準に従う必要は無い。
>>11 まぁお前の考えが下に続いていれば少しは格好もついたけど、
そんなヒステリーじゃ話にならないな。
13 :
デフォルトの名無しさん :2007/08/02(木) 06:17:45
屁の音
>>12 やっぱ、自分で書いたものをコピペしてたのか
よっぽど、いいこと書いたと思ってんだなw
何が「やっぱ」なのか意味不明なんだが。 変な電波受信してるんじゃないか? ヒステリーって言われたのがこたえたのかな。
>>8 どっちも専用スレあるだろ。
TR1、TR2の話題ならここでもよかろ
18 :
デフォルトの名無しさん :2007/08/02(木) 09:16:48
>>10 の頭の弱そうなスレみつけてちょっと遊んでみました。
ごめんなさいもうしませんこたえました。
また立てちゃったの?
立った以上はまあ、有効活用するしかない。
そこで鮮やかに俺が初歩的な質問に有効活用ですよ vector<T> hoge; // 自作クラスのコンテナ vector<size_t> fuga; // 上記コンテナの添え字コンテナ ・・・な配列があったとして、以下の処理をループ使わずにやるにはどうすりゃいいですか? vector<T> result; for (vector<size_t>::iterator it = fuga.begin(); it != fuga.end(); ++it) { result.push_back(hoge[*it]); } 多分こんな感じになるんじゃなかろうかと思うんだけど、 for_each (fuga.begin(), fuga.end(), ??); これしきの代入に関数オブジェクト自作して放り込むのも大げさな気がして 予め用意されてる関数とかでサクッとできる方法ってあります?
back_inserter使ったらだめなん
boost::permutation_iterator
さくっと typedef vector<T>::reference(vector<T>::*at_t)(vector<T>::size_type); transform(fuga.begin(),fuga.end(),back_inserter(result),bind1st(mem_fun(static_cast<at_t>(&vector<T>::operator[])),&hoge));
>>21 ここらへん組み合わせればなんとかなりそう。
transform back_inserter mem_fun vector::operator [] または at
26 :
25 :2007/08/05(日) 14:46:44
うは
>>24 乙。
bind1st が抜けてたか。
しかし、これは読みにくいな。
STLスレって結局Boost使えばこうできるって話になるから嫌。 分けないで前みたいなC++テンプレートスレみたいにでもすればいいんだ。 23の言っているboost::permutation_iteratorだとこんな感じ。 result.reserve(hoge.size()); std::copy( boost::make_permutation_iterator(hoge.begin(), fuga.begin()), boost::make_permutation_iterator(hoge.end(), fuga.end()), std::back_inserter(result));
うお・・・transform + back_inserter ってこういう使い方できるのか・・・ 「何らかの処理施してコピー」なんて解説されてるの読んでピンと来ず。。 「別のコンテナの中身を引っ張ってくる」って処理もアリなわけね。 今回の例みたいな単純な代入だとループに逃げそうになるチキンな俺だが しかしこれを手がかりに色々と応用試せそうだぜ!おまいら愛してる!
std::copy + ostream_iterator STL習いたての時、で画面にprintできる事に感動したなぁ
試すのはいいけど、そういう書き方ってみんなしてるもんなの?
個人的には
>>24 みたいなコードあんまり読みたくない・・・
31 :
27 :2007/08/05(日) 15:41:57
俺はやらない。だってBoostがあるから。
32 :
デフォルトの名無しさん :2007/08/05(日) 15:43:06
BOOST_FOREACH(size_t val,fuga) { result.push_back(hoge[val]); }
33 :
21 :2007/08/05(日) 16:01:17
今まで標準に含まれてるstlすらマトモに使えてないのにboostに手を出すと 俺の頭がboostするに違いないと思って手をつけなかったのだが・・・ いい機会だから試してみようかしら。 どう思われる? transformとかもマトモに使いこなせてない俺なわけだが。 今なんか const なメンバ関数を mem_fun に投げ込もうとして コンパイラに長々と説教頂いておりますよ
smart_ptrをはじめ、cstdint, static_assert, utilityなんか使いこなすも何も無いだろ?
36 :
24 :2007/08/05(日) 16:18:29
>>30 あんな自己満足コードを正気で書く奴は(多分)いないね。
あんなコードを仕事で見せられたら俺なら殴るね。
37 :
21 :2007/08/05(日) 16:36:33
>>36 もう少しで殴られるとこだったか(・∀・;
今回の例程度の状況ならさっさとループで済ませて次にかかるとしよう
いずれにしても今回教えてもらった事は他の場面で活用するぜ
boostも近いうち試してみる
はしかみたいなもんかもな 「ループ使ったら負け」とかいう病気
仕事ならループにするなあ メンテは自分だけがやるわけではないし
どうせループでも関数合性でも読みにくいんだから慣れが要らないループの方が増し。
// 上のコードは以下のループと同等 // ... って両方のっけとく。 そしてわざわざ1行に下意味をなさなくなる
foreach (counter i, counterble_range(start,end)) { ... } ぐらいなら読める人結構いると思うぜ
43 :
デフォルトの名無しさん :2007/08/14(火) 01:11:34
STLやるなら、やっぱEffectiveSTLは必読?
>>43 書いてある内容を知ってないといろいろ嫌なことが起こるだろうとは言える。
Web 上にも同様の情報はあるので、本が必要なわけじゃない。
読み物としてはそこそこ面白かった。 必要とか不必要とかじゃなく「おすすめの一冊」
勉学に近道なしというが、読めば道程を多少なりともショートカットできる稀有な本。
ちょいと質問。 template<typename T> void func(std::vector<T> foo) { std::vector<T>::iterator it; } こういうことをしようとするとerror: expected `;' before "it"になるのだけれど なんかいい方法はないだろか。要は、forループで使いたいわけだが。
typename std::vector<T>::iterator it;
49 :
47 :2007/08/14(火) 19:36:27
晒してみるテスト。
ttp://www5c.biglobe.ne.jp/~ecb/cpp/07_18_03.html >fill_n void fill( FwdIt first, Size n, const T& x ) firstからn個分の要素をxで満たします。
おいおい、コピペミスにもほどがあるぞ。
ttp://www005.upp.so-net.ne.jp/episteme/html/stlprog/algorithm.html#algorithm >- template<class OutputIterator, class Size, class T>
> void
> fill_n(OutputIterator first,
> Size n,
> const T& value);
あれ? エピたん……
ttp://www.s34.co.jp/cpptechdoc/reference/stl_samples/algorithm.html#std_fill >- template<class OutputIterator, class Size, class T>
> void
> fill_n(OutputIterator first,
> Size n,
> const T& value);
おやー? しかもここ、エピたんのぺーじにそっくりだけど。
ttp://docs.sun.com/source/819-3704/fil_4628.htm >template <class OutputIterator, class Size, class T>
> void fill_n(OutputIterator first, Size n, const T& value);
あれ、ここもか。
fill_n()がOutputIteratorを返すってのはローカルな拡張なのか?
ttp://www.informatik.uni-freiburg.de/~danlee/fun/STL-doc/STL/Fill.html ttp://www.wakhok.ac.jp/~sumi/stl/header/algorithm.html この辺を初め、OutputIteratorを返すとしているところも多々あるにはあるのだが……
規格見りゃ分かる template<class OutputIterator, class Size, class T> void fill_n(OutputIterator first , Size n , const T& value);
52 :
50 :2007/08/16(木) 18:05:56
ほほぉ、THX! すると、1番目は論外として、2-4番目は正解ってことね。 # まぁ、4番目の丸ごとコピー疑惑はあるにしても。 で、5-6番目はgccの拡張を取り上げたのかな?
へー、 引数が前方反復子だと戻り値がvoidで、出力反復子だと出力反復子になる実装があるのか。 具体的になにが便利でどう使い分けるのかがよく分からないけど…
54 :
50 :2007/08/16(木) 18:55:51
>>53 いや、1番目のは間違いだらけだから無視して。
で、gccの実装はこう。
--
template<typename _OutputIterator, typename _Size, typename _Tp>
_OutputIterator
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
--
つまり、fill_n()は__first + __nを返す仕様になっている。
libcomoも_first+nだった。SGISTLの実装っぽいなぁ
std::vector、listでのeraseの使い方で質問があります。 eraseで指定された要素を削除する場合、ifで分けて以下のような操作をしなければならないのでしょうか? なんか、if,elseで分けるところが美しくないのですが、もっと良い書き方があれば教えてください。 std::vector<int> array; ↑には複数の要素があるとする std::vector<int>::iterator itr; for (itr = array.begin(); itr != array.end();) { if (*itr == 5) { itr = array.erase(itr); } else itr++; } }
事前にremove_ifでいらない要素をうっちゃってからerase これ基本
5と等しいかどうかで削除してるんだから ただのremoveでよくね?
59 :
56 :2007/08/16(木) 19:40:08
>>57-58 できました。ありがとうございます。
struct Hoge{
int a;
int b;
};
という構造体があり、intのコンテナではなく
std::vector<Hoge>
だった場合、
Hoge構造体のaの値を見て、削除する場合はどうすればいいのでしょうか?
if (* itr == 5) ↓ if (itr->a == 5)
operator int() { return a; }
>>61 一瞬惚れそうになったが
intに直接変換できちゃ困るかもしれん。
比較のためだけのクラスを作って、それに変換するってのはどうだ?
(関数オブジェクト作る方がいいんだろうけど)
vectorについて質問します。 class Parts{ 略 } class A { Parts* parts; A(){ parts = new Parts();//コンストラクタで生成して } ~A(){ delete parts ;//デストラクタで破棄する } 略 } というようなクラスがあったとしてそれをvectorに格納したいとき std::vector<A> vec; function(){ A a ; vec.push_back(a) ; } とすると、Aクラスのデストラクタが2回呼び出されて 中身の無いポインタをdeleteしてエラーになるようです。 なぜvectorがデストラクタを呼ぶのかなどなぜなのかとどうすればいいか 詳しく解説があるようなところがあれば教えてください。 素人考えでは やはりSTLの補完としてのBoostのスマートポインタが必要なのでしょうか。
>>63 vector<>に格納する時にAのコピーコンストラクタが呼ばれるが、
Aではそれが定義されていないので、デフォルトのコピーコンストラクタが
呼ばれ、ポインタメンバのpartsが単にコピーされる。
結果として出来るAのインスタンスは2個だが、どっちもpartsは
同じPartsインスタンスを指しており、それぞれのAが破棄されるときに当然
問題が起きる。
まともに機能するコピーコンストラクタを自分で定義する(この場合は
多分リファレンスカウントを自分で実装することになる)か、
Partsのポインタではなくリファレンスカウント式のスマートポインタを
持つようにするんだな。
>64の通りだが、まずはEffective STL読め。 stlコンテナは常にコピーコピーコピーコピーコピーコピーコピー。 安全にコピーできるオブジェクトでなければコンテナに入れちゃいけない。 慣れてきたらリソースの所有権について常に考えるようにすると良いよ。
>>63 class A のメンバに
A(const A &x) : parts(new Parts(*x.parts)) {}
を追加するとかそういう意味合いもあったりなかったり
現状の class A 自体が class としての機能を満たしてないから
ちゃんと実装してやった方がおばちゃんモアベターよ
63です。 64 65 66 のみなさま、 迅速、かつ誘導ではなくこちらでお答えくださってありがとうございます。 なぜpush_back()でデストラクタが呼ばれるかは分かりませんが、 コピーコンストラクタの実装で解決できることを理解できました。 >64 同一のインスタンスでなくてもよかったので(概略からはわかりませんが) 新しくインスタンスを作って値はすべて同じでいちおう動きました。 >65 >コンテナは常にコピー 補足、アドバイスありがとうございました。 >66 STLと別の話になってしまいますが クラスとしての機能とはどんなものでしょうか。 それが私にはまだ分かっていないので>63のような質問をすることになるのかもしれません。
悪いこと言わんからEffective STL読め。 手っ取り早くはboost::shared_ptr使うのがベター class Parts{ //略 } class A { public: A() : parts_(new Parts) {} private: boost::shared_ptr<Parts> parts_; //略 }
> なぜpush_back()でデストラクタが呼ばれるかは分かりませんが、 RAIIを勉強しなさい。 function()のスコープを出るときにA aが破棄されるのでデストラクタが呼ばれる。 あと、std::vectorはどの時点で内容をコピー&破棄するか判らないので、 function()のスコープの前にデストラクタが呼ばれる可能性もある。 結局のところ、class Aはコンテナに納める要件を満たしてないので入れちゃダメ。
すみません初歩的な質問なんですけど using namespace std; って使わない方がいいって良く言われますけど、 面倒でも std::vector<> って使った方がよいのでしょうか?
ヘッダ内で using namespace 〜 を使うとまずいような「気がする」という話だからなぁ 自分だけで使うことが確定してるヘッダなりプロジェクトなりだったらガンガン使おうがNP using std::vector; とかで以後 vector<type> として使えるからごく個人的にはこっちをお勧めしておきたくて愛
>70 影響範囲を考えて判断すべし。 ・ヘッダ(関数スコープ外): 他のソースにも影響するから避ける ・ソース:全てのヘッダをインクルードした後ならば影響は小さい。 ・関数スコープ内:問題なし。問題あったら関数を修正。 なんで、ケースバイケースですな。
>>70 少なくともヘッダの中で一切スコープで囲ってないとこでやるのは
止めといたほうがいいんじゃね
それがそのままソースにまで取り込まれるからな
自分のnamespaceなり何なりにくるんで、その中で使う分には、まあいいんじゃね
よくわかりました ありがとうございました
75 :
デフォルトの名無しさん :2007/08/30(木) 21:42:59
int型のx,yをメンバとする構造体(data)をvectorに格納し、xを基準にソートしています。 ここで、xの値が特定の範囲内に収まっているもの(30〜50とか)を検索しようとしています。 lower_boundで下限側の検索はうまくできましたが、upper_boundによる上限側の検索がうまくできません。 lower_bound に渡す関数オブジェクトは以下のようにしてうまくいけてるようです。 struct Comp:public binary_function<const data&,const int& ,bool> { result_type operator()(first_argument_type prm1,second_argument_type prm2)const if(prm1.x<prm2) return true; return false; }; upper_bound 側についても上記と同じように書いてみたのですが、コンパイルエラー などがでます。どのように記述すればよろしいでしょうか。 よろしくお願いします。
知らんけど、 int < data を書かないといけないんじゃない?
>75 同じようにっていうか、それをそのまま渡せばいいんじゃないの?
78 :
デフォルトの名無しさん :2007/08/30(木) 23:26:14
早速の回答、ありがとうございます。 「int<data を書く」とは具体的にはどのようなことなのでしょうか? よろしくお願いします。
>>78 >>75 は読んでないけど
>>76 の言ってる意味は
bool operator<(int, const data&) のことでは。
80 :
デフォルトの名無しさん :2007/08/30(木) 23:42:01
>>77 low=lower_bound(array.begin(),array.end(),20,Comp());
この場合は正常に取得できます。
以下のようにupper_bound にそのまま渡したのですが
upp=upper_bound(array.begin(),array.end(),30,Comp());
この場合にコンパイルエラーがでてしまいます。
:1番目の引数をconst int からconst struct data& に変換できません。
>>79 bool operator<(int, const data&) を定義して関数オブジェクトを使用
しないほうがいいのでしょうか・・・。
そちらも試してみます。
81 :
デフォルトの名無しさん :2007/08/30(木) 23:59:16
bool operator<(int, const data&)と bool operator<(const data&,int) を定義しておけば lower_bound(array.begin(),array.end(),20) upper_bound(array.begin(),array.end(),30)で上限下限が取れました。 ですが、場合によってはメンバのyによる範囲検索もしたいので 以下のような関数オブジェクトを指定たいのです。 struct Comp:public binary_function<const data&,const int& ,bool> { int m_nType; Comp(int nType){m_nType=nType;} //1:x比較 2:y比較 result_type operator()(first_argument_type prm1,second_argument_type prm2)const { if(m_nType==1) { if(prm1.x<prm2) return true; return false; } else { if(prm1.y<prm2) return true; return false; } } }; どのようにすればよろしいでしょうか。 よろしくお願いします。
upper_bound 用の、引数の順序を逆にした関数オブジェクトを作る
関数オブジェクトはひとつでいいよ。オーバーロードを追加するだけでいい。
84 :
デフォルトの名無しさん :2007/08/31(金) 18:48:57
>>82 ,83
ご回答、ありがとうございます。
無事解決できました m(__)m。
85 :
デフォルトの名無しさん :2007/09/05(水) 22:06:05
listの2次元配列の質問です。 listの行の要素の増加をどういう風にすれば良いのかが分かりません。 list< list<int> > i; i.pushback(100); これではエラーが出てしまってできません。 もう一つ。 配列の列の要素の最初と最後の参照はできるのですが、 途中の要素の参照の仕方が分かりません。 list< list<int> >::iterator it = i.begin(); it.***->x = 1000; //***番目のxに1000を格納したい 1次元の配列だと問題ないのですが、2次元だと良く分かりません。 解決できる方、お願い致します。
pushbackでは駄目だろうな
っつうかlistのlistなのに「何番目」とかランダムアクセスしようとするのはアホだろ deque使え
>>87 ランダムアクセスというかfor文で順次アクセスしたかったんですけどね。
書き方悪かったです。
dequeですか。
ありがとうございます。listに拘りすぎました。
>>88 typedef std::vector<int> line;
typedef std::vector<line> table;
line l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
table t;
t.push_back(l);
t.push_back(l);
t.push_back(l);
std::cerr << t[1][1] << std::endl;
t[1].push_back(4);
std::cerr << t[1][3] << std::endl;
90 :
デフォルトの名無しさん :2007/09/06(木) 02:50:07
>it.***->x = 1000; //***番目のxに1000を格納したい >ランダムアクセスというかfor文で順次アクセスしたかったんですけどね 矛盾してますが何か?
これがゆとりか ...
ひょっとしてこんなコード書きたかったんだろうか。 list< list<int> >::iterator it = i.begin(); list<int>::iterator jt = it->begin() for(int i = 0; i < 500; i++) {jt++;} *jt = 1000; // 500番目に格納 う、うひぃ。
atd::advance
94 :
デフォルトの名無しさん :2007/09/14(金) 19:08:48
初心者なんですがSTL使うと読みにくいです。 慣れの問題ですか?
脳の問題
初心者なんですがSTL使うと エラーメッセージが頓珍漢で 原因ンが把握しにくいです。 慣れの問題ですか?
脳の問題
初心者なんですが このスレの住人うざいです。 脳の問題ですか?
慣れの問題
>>98 うざければこのスレ開かなければいいだけの話。
お前は馬鹿。
なにこのひと
さぁ
むきになんなよ
STLをすてる
Su Te Lu
誰がうまいこと言えと
STLって現場では当たり前に使われてるんですか?
現場による。 「全員にSTL教育しないと読めない奴が出てくるから」って理由で禁止してる現場もあるし、 個人の裁量任せになってる現場もある。 しっかりモジュール分割がされてるプロジェクトだと ヘッダファイルを読み込むだけだからSTLだろうがBoostだろうが許可されることも。 ちなみに俺のところは、 「コンパイラ付属のライブラリなら、コンパイラ屋がサポート責任を持つからOK」 って事になってる。 (バグ・ドキュメント不備を見つけたらMSにゴルァ)
109 :
108 :2007/09/16(日) 01:19:05
最後の行は、 「VCのバグを見つけたら」って意味ね
110 :
108 :2007/09/16(日) 01:28:31
ついでに 俺のところは社内で開発したライブラリが結構充実してるので 末端のコーディングでSTLを使う場面があまりない。 まあ、保守を考えたら、 末端があまりに前衛的なコーディングをしてたら嫌がられるだろうな。 Boostはともかく、 STLでも深入りすればそれなりのおつむレベルが要求されるから。
111 :
107 :2007/09/16(日) 01:43:20
なるほど。 現場次第なんですね。 うちではあまり使われてないです。 うちの現場はヘポーコなんで リスト構造とかいちいち自前で作成してるアフォが多くて
VC7.1のvectorとか怪しいと思ってる。 memset(&(v[0]), 0, v.size()) 規格上は問題ないはずだが、これをやるとおかしくなる。 仕事ではSTLの利用は警戒した方がいいと思う。
>>112 size()の戻り値は要素数じゃね?
memset()の最後の引数はバイト数じゃね?
>112 v の型は何よ?
116 :
デフォルトの名無しさん :2007/09/16(日) 04:10:18
STLすら分からないって よっぽど見るに耐えないコーディングしてるんだろうな。 美的センスのないコードはバグの温床になるから嫌い。
自分とこの現場もかなりレベルが低い。 わからないのを人のせいにしてくる始末。 わからない人でもわかるようにコメント書けとかいってくるw おまえが勉強しろよって感じ。技術者としてどうよって思う。
ツールも規約も方法論も、現場のレベルに合わせて決めてるよ そうしないと先にすすまないもん
>>112 ひさびさにバイト長と要素数の間違い犯してる香具師みた。
誰もが一度は犯す過ちだよな…
STL使えないレベルの現場だとC++使わせないのが正解だよな。 素人にチェーンソー使わせるなんて危なっかしいことしない方が良い。 でも、easy Cとして使えそうなのって他にないんだよな……用途限定でJavaぐらいか。
そういうことでD言語だけど、すぐに一般化しそうな気配じゃないしな
>>119 バイト長とは変わった肩書きだなぁ、とかイミフなことを思ってしまった
バイト見習い→バイト→バイト長
バイトにまで上がれば出世は楽だけど、 ビット長からバイト見習いに上がるまでがきつい
ニブルを経由するんだ!
ボクはニプルのほうが好きです
>>108 は、VCの付属ならOKだけどSTLPortは不可ってことだよね?
”会社で使うコンパイラにSTL付属してるけど、他のSTL使ってる”って人はどんくらいいるのかな?
よければ教えて欲しい(なんとなく知りたいだけだから無視してくれてOK)。
うちは、STLPort使ってる。うちの会社の使い方でパフォーマンスよかったから。
VC付属のを使っています Boostも使っています。 STLport を使うと早くなるのかなぁ〜
#include <stdafx.h> #include <iostream> #include <vector> #include <algorithm> void show(int i) { std::cout << i << "\n"; } int _tmain(int argc, _TCHAR* argv[]) { std::vector<int> v; int i; for(i=0;i<10;i++){ v.push_back(i); } for_each(v.begin(),v.end(),show); return 0; } ↑のコードでshowに引数を書いてないのに iが順番に出力されるのはなぜですか?
>>128 for_eachが内部でshowを呼んでいるから。
引数はどうやって判断するんですか?
質問が成立してない。言い直してくれ。
132 :
デフォルトの名無しさん :2007/09/17(月) 08:00:38
std::map に count メソッドがあるのはなぜですか? count() // xをキーに持つ要素の数を返す。 size_type count(const key_type& x) const; だそうなのですが、そもそも map だと x をキーに持つ 要素の数は高々1なので、count というよりは bool で済む気がするのですが、これは multimap のことも 考えてのことですか?
>>128 そのfor_each()は次のコードとほぼ等価だ。
--
for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) show(* it);
--
ついでに言えば、最適化によって次のコードともほぼ等価になる。
--
for (unsigned ic = 0; ic < ic.size(); ++it) show(v.at(ic));
--
どうでもいいが、C++なのだから変数のスコープはちゃんと意識して書くべきだ。
# 関数の先頭でループ制御変数を宣言するなんて恥ずかしいと知れ。
>>132 普通に考えて、count という動詞が来たら結果は数だから。
empty なら bool だけど。
>>130 for_eachの実装はこんな感じ
template <typename In, typename Fun>
Fun for_each(In first, In last, Fun f)
{
for(In it = first; it != last; ++it)
f(*first);
return f;
}
fとしてshowが渡されるわけだから、showを呼ぶときの引数は*it。
itは引数として渡された区間を舐めるイテレータだから、
この場合mainのvの要素を順番に指すことになる。
ああごめん、なぜ count があるかという問いだったか。 STL の標準版アルゴリズム群で map を操作するのは効率が悪いので、 map 専用版も用意することになった。同じアルゴリズムには同じ名前を 使いたいので count もそのまま残った、ということでしょう。
>>128 配列の中身に0から9の値が順に格納されているから。
それを順に取り出して表示しているので、0から9の値が順に表示されるというだけ。
138 :
128 :2007/09/17(月) 14:38:18
for_eachの実装がわかってカラクリがわかりました ありがとうございました
139 :
デフォルトの名無しさん :2007/09/17(月) 16:06:52
STL はこれからも進化し続けるの? もっと便利なコンテナも登場するの?
つboost とか言われるとboost厨uzeeとか言われるんだだろうなぁ
C++0xスレに行ってくればいいんじゃね 念願のハッシュとかあるぜよ
最近boost使い始めた
std::stringを引数にとる関数の場合 スタックに積まれるのは文字列全部ですか?
>>143 スタックにはクラス本体だけ。
文字列自体はヒープに確保される。
>>139 C++0xでコンセプトが導入される予定なので
次期or次々期のSTLは全体的に書き換わるのではないかといわれている。
コンセプトの導入をもって HaskellはC++のサブセットになります
それはないだろw
148 :
デフォルトの名無しさん :2007/09/17(月) 21:55:12
>>144 じゃ、 const std::string& で引数をとるのはあんまり意味ないかな?
いや、そのコピーコンストラクタでそのヒープの中身を 複製する実装も少なくない(下手したらこっちが主流かもしれない)だろうから、 依然としてconst参照にすべきだと思う。俺はそうしている。
>>148 参照ならアドレス渡すだけだけど、値渡しなら、コピーコンストラクタが呼ばれるんじゃね?
文字列本体をヒープにもってて、参照カウンタをもってるような実装でも。
>>148-150 コピーコンストラクタは文字通りコピーを作るんじゃないかな。(それが目的だと思っている)
だからconst参照を選ぶ。
>>133 > どうでもいいが、C++なのだから変数のスコープはちゃんと意識して書くべきだ。
どうでもいいが、VC6だと変数のスコープがブロックの外になっちまうんだよな…
>>152 いいえ。ブロックの外になることはありません。
forの外はブロックの外とは言わない罠。 for (int i = 0; i < N; ++i) func(i);だったらそもそもブロックなんかないわけだし。
規格厨、出番ですよ〜!
むしろ双方気づいていて、
>>155 は揚げ足を取ってるだけ
for(int i = 0; i < 9; i++) {} cout << i; // ここでiが見えることだろ
そうだね
#define for if(0);else for これで解決するかな?
165 :
デフォルトの名無しさん :2007/09/18(火) 19:54:58
それif(1)forじゃだめなの?
>>162 たまたま偶然見えてるように見えてるんじゃないの?
deleteやfreeで解放しても、しばらくは見えてるのと同じ理由だと思うの...
>>165 それだと後ろにelse ifが続いたとき対応がおかしくなる。
>>166 ちがうよ。
VC6は本当にスコープが外れない。
>>166 有効範囲(scope)と生存期間(extent)を区別しろよ。
構文的な有効範囲の外では名前自体が使えない(コンパイル時エラーになるべき)のであって、
寿命の尽きたオブジェクトを参照するのとは話が違う。
>>155 >for (int i = 0; i < N; ++i) func(i);
これって「暗黙のブロック」みたいな言い方しないっけ?
>>152 >>162 の様なソースの外側のブロックでiが別の定義されてないか?
されてない場合で言ってるんだよ
>>170 言う。
けど、for内で宣言した変数が162のように外側でも見えるVC++ 6やARMだと、
forは暗黙のブロックを作らないのではないのかと思う。
そして、ISO C++ではforも暗黙のブロックを作る対象になっている (§6.4)。
(確かめたのはJIS X3014なんだけどさ)
ARMは今手元にないからわからない。
forのスコープを標準に準拠させられるのはVC7からだっけ? VC8からはデフォルトで7.1はオプションだったのは覚えてる
VC6でも/ZaでMS独自拡張を切るとforもISO C++どおりになるが、 標準ライブラリもまともに使えないと聞いたことがある。 自分で試したのではないけど。
つまりこういうこと? #include <stdio.h> void main() { for( int i = 0; i < 10 ; i++ ) printf( "%d", i ); for( int i = 0; i < 10 ; i++ ) //2重定義でエラーの出るコンパイラがある printf( "%d", 10 - i ); }
初めてSTL使ってみた初心者です。 配列の大きさ気にしなくていいので楽ですね。 便利な関数もいろいろあって役に立ちそうです。 なにを今さらなことなんですけどw
コンテナが便利とか言っているうちは素人。 ファンクタ関連の貧弱さに怒れるようになって初めて一人前。 精進せい。
いいんじゃね
最初はvectorだけ使うとかで
そのうち色んな順番でソートしたいとか連想配列使いたいとか欲求がでてきて
>>178 になってboostへ
shared_ptrが使いたいが為にboostを使い始めて、 今ではどっぷり浸かってます。
テンプレートメタプログラミング厨はどこに行き着きますか?
1. テンプレートの書きにくさに絶望します。 2. 関数型言語を知って狂喜します。 3. コンパイル時計算が書けないことに絶望します。 4. Lispのマクロを知って狂喜します。 5. 型をベースにした計算ができないことに絶望します。 6. もう逃げ場がないので、自ら命を絶ちます。
そこで俺様言語開発
コンパイル時に型付き計算できるC++マクロを開発すりゃいくね?
C++では何をするにも複雑すぎる Dも既に十分すぎるぐらいに複雑な変態言語だが、それでもC++よりはずっと簡潔に コンパイル時計算が出来る template factorial(int n) { static if (n == 1) const factorial = 1; else const factorial = n * factorial!(n-1); }
逆に考えるんだ。宣言的マッチを強制するC++の方がモダンだと。
モダンって今時言わないよw ナウだね。ナウい。
ナウい C++ デザイン あんどりゅ・あれきさんどれすく
STLよりboostを使うほうがベター?
ほとんどはお互いを補完しあう存在なので、どっちがベターと言えるものではない。 std::bind1st類とboost::bindといった具合に、 機能が完全に重複することは、ないわけではないが稀。 ただし、こういう場合は間違いなくBoostのほうがベター。
コンパイルにかかる時間は増えるけどな
コンパイラがもっと最適化されればいいんだ
ovenとか使わせてもらっててクリーンビルドに30分ぐらいかかるけどあまり気にならないよ その間別の事すればいいだけだし プリコンパイルヘッダ使えばその時間も短縮される
194 :
デフォルトの名無しさん :2007/09/20(木) 14:03:01
作成中はコンパイル最適化しないほうがいいよ STLとかコンパイル断然速くなるよ
「作成中」の真意が分かりかねるが、 デバッグビルドで最適化しないのは当然だろ。
196 :
デフォルトの名無しさん :2007/09/20(木) 22:10:32
Qtしか使った事がないので、QValueVector QPtrVector 等しか使った 事がありませんが、STL と比べるとどうなんでしょうか? 全部読んでないのですが、皆さんはテンプレート機能を使って、 新規にテンプレートクラスを制作しているのでしょうか?
テンプレートだけならそんなに敷居は高くないが、 ファンクタやら独自コンテナやらを自分で書ける奴は多くなさそうだ。
198 :
デフォルトの名無しさん :2007/09/21(金) 10:31:53
コンテナに投入するクラスって、 デフォルトコンストラクタがなければだめなんですよね?
push_backやassignにインスタンスを渡すならコピーコンストラクタとかコピー代入オペレータも必要になるかも
>>198 サイズ指定のみのコンストラクタ、サイズ指定のみの resize() 、 map の operator [] () の
どれも使わないのであれば必要ない。
むしろコピーコンストラクタとコピー代入演算子のほうが広く必要とされる。
201 :
デフォルトの名無しさん :2007/09/21(金) 16:25:08
>>200 なるほど。
○○のコンテナに入れるなら、あるいは○○の機能を使うなら
○○を満たしていなければならない、みたいな取り決めを知るには
やっぱり正式な仕様書を読まなければなりませんか?
今のところコンパイラが出すわかりにくいテンプレートがらみの
エラーメッセージ見ながら、「う〜ん、このテンプレートで
エラーが出てるんだからこれができなくって怒られてるんだろうなぁ」
とか推測しながらやってます。
>>201 今はそうするしかない(将来的にはソース上に書き下せるようになりそう)。
テンプレート引数に要求される事柄は、
一般にコンセプト (concept)とか要件 (requirement)と呼ばれる。
C++の規格書であるJIS X 3014は、
ttp://www.jisc.go.jpで見れる 。
閲覧出来るけど印刷不可かあ。
つ PrintScreen
つ[キャッシュ]
206 :
デフォルトの名無しさん :2007/09/22(土) 15:06:18
つ 通報
全部ポインタにすれば解決
いつも思うんだけど、何でこんなにJISはケチ臭いのか 言語を普及させるつもりないのかな
はい
ISOなんか金払わなきゃ落とせないんだからJISのが全然良心的
ISO のほうならドラフトがダウンロードできるから助かる。
ISOはeMuleかtorrentで(ry
214 :
デフォルトの名無しさん :2007/09/23(日) 08:20:53
JISって公的資金に頼ってるんじゃないの? 完全に独立採算な団体なの?
半官半民じゃね?
216 :
デフォルトの名無しさん :2007/10/02(火) 08:30:45
STLのlistってオブジェクトがなくなったとき コンテナの中身も削除してくれますか?
コンテナの中身「は」削除してくれます
ということは、コンテナの中身がポイントしているオブジェクトは削除されないんですね?
そうです スマートポインタを使いましょう
new するようなケースは大体全てにスマートポインタ使うべきでしょうか?
スマートポインタの使用のコスト(一般的に生ポインタより遅く容量を食う)が問題にならない場合は使うべきです コンテナに使用する場合は全適用しちゃっていいでしょう ただしstd::auto_ptrはリソースを共有する際問題になることがあるので控えましょう effective C++第三版の3章にわかりやすい説明がありますのでそこを読むと良い解が得られるかもしれません
結局のところお前らBoostをどう思ってるの?
ブスっと見つめる
>>222 無いと困る。
serialization とか shared_ptr とか特に。
preprocessorとかmplとか特に
次のバージョンがすごすぎて ほんとにリリースできるのか不安になる
0xの話でも意味が通じるw
コンテナに突っ込む前にコンセプトチェックしようと思うんだけど、 どうすればいいの?コンセプトチェックは boost::concept_check 使うとして、どのコンテナに入れるにはどのコンセプトを満たして いなければならないってのはどこにリストがあるの? SGI のドキュメント嫁?
複数の入力ファイルを渡したいとき、 いっぱい std::ifstream 開いておいて foo (std::vector<std::istream>& streams) { ..... } みたいにして渡すのは邪道?そもそもストリーム自体を コピーしたりしていいんだろうか、という疑問もある。
TR2まだあ?
233 :
231 :2007/10/02(火) 18:43:18
バカなこと考えずに std::vector<boost::shared_ptr<std::istream>> 渡すことにしました。
>>231 残念ながら、std::istreamは
AssignableでもCopyConstractableでもないので複製できない。
ifstream複製しようとする奴はじめて見た
前にも見たことあるけど FILE*のようにストリームを変数に入れておこうという考えを 持つのはごく自然なことで、 std::streamがコピー可能であることを知らない初心者がはまる ありがちな罠なんじゃないの
>>236 だからコピー可能ではないと思うのだが。
たぶん 「コピー不可能であることを」 のタイポかな
ああそのとおり、すまんねtypoだ
質問です。 map< int , string > とした場合、要素側stringの検索は foreachするしかないでしょうか?
>>240 map< string , map::iterator > という手もあるかもね。
242 :
デフォルトの名無しさん :2007/10/08(月) 03:49:50
>>242 string をキーとした検索用の map を追加で用意するってこと。
もちろん更新は必ず同時に行う必要があるから、それらを包むクラスを
作ることになる。
面倒だから、検索速度に不満がなければループまわして探しとけ。
244 :
240 :2007/10/08(月) 04:04:12
>>241 早速にありがとうございます。
int key = hoge["hogehoge"]->first;
ということですね。 やはり専用関数は無いも
のなんですね。(重複とか面倒そうですもんね)
map2本立てで検討したいと思います。
>>244 boost::multi_index_container
テンプレートを使い始めたら、分割コンパイルで、リンクする際にエラーが出るようになってしまいました。 分割しなければ問題ありません。非常に単純なプログラムでも、テンプレートがあるだけで、 リンクに失敗します。対処方法を教えてください。
クラス・関数テンプレートは全てヘッダに書く。
248 :
デフォルトの名無しさん :2007/10/08(月) 17:18:48
エスパー様、とちゃんと宛先を書け。 または、現象を再現させる最小のコードを貼れ。
つExceptional C++ Style : 9. キーワードexportの制限
exportがまともに動作するコンパイラってあるの?
そんな予約語はなかった
252 :
デフォルトの名無しさん :2007/10/08(月) 21:08:18
253 :
デフォルトの名無しさん :2007/10/11(木) 01:44:40
初心者なんだけど list使ってみたら添え字でアクセスできないのが 思った以上に不便に感じた('A`)
list は連結リストだから、添え字アクセスなんか仮に出来ても遅いぞ vector 使っとけ
おうvectorマンセー!!
vector はメモリアロケート対策に何も考えないと指数的にメモリを喰うぞ list に要素本体格納して vector にそれへのポインタ入れとけ
え?
,.へ ___,.へ __,,. --─'──`<.,,/:::::::ト、 ,. '" `'く:::::::ト. ∧ / ゝ____,.へ--、へr-、ノ i、::::! | /! V i__,.へ!_,./--'─'--'-<ヽi__/ Y | /」 __i. r'へ,.イ / ハ ハ i `ヽ7、.| .|/ ∠__,.ヘ `Y´ / / ハ__/,.ィ レ' レヘ、_!_ i iヘ| |<> /iヽ. i イハ /i rr--'テ ,r-テiレヘ i | | !/ !., | V :| ゞ-' ヽ' ハ ハノ| |> いくらこのスレでも許容限度があると思う。 ∧ `ヽ、ノ 〈 ハ " "从ヽレi. | V /!〈rヘハ!|`ヽ、.,_ ´ _,,.イハ ハ〉 レ' |/ / レ/´ ̄`ヽニ7´ト、!/ Vヽ> !/〈 `ヽムi i/ ヽ_r、_イヘノハi_,.r〉 i:::ヘ ',:::::/ / ,.rく::/::ハ ヽ7 /ト、 ,r<:::::::ヽ::〉 i/イ_:::\、 ri ´ ̄ ̄7 ̄7'^ヽ'ヽ. `iヽ、 くL!、.,______,,.l____i, i i_ノ_ノ::> ヽ-'^ー'  ̄
なんというテンプレ候補
添え字でアクセスできるリストってないの?
そんなlist構造の存在意義を否定するようなもの、STLにはない。
別にランダムアクセスが遅いことがリスト構造の存在意義じゃないだろ。 実際、双方向リストを拡張してランダムアクセスに比較的強いデータ構造を作ることもできるはずだし。 STLにはないけど。
boostにあるmulti_index_containerがその要求に応えてくれる筈
[]演算子を自分で定義すればできるよ!できるよ!
std::map<int, hoge>
その場合のhashがlist構造になることは保証されているのでしょうか?
STLにはhashがありません。
STLって、実装は規定しないんじゃなかったか? 両進イテレータでアクセスできるとか、 最悪でも線形時間で処理が終わるとか そういう言い方で規定してるような。 だから、内部的にhashを持つlist実装も不可ではないはずだ。 常識的にはtreeで実装するがな
現状O(1)で済む処理がO(1)にならなくなったり iterateしながらの挿入削除といった操作に対して弱くなりそうだが
>>268 map はソート済みシーケンスになる必要があるから、ハッシュは使えないと思う。
任意の型のキーに対してハッシュ値を計算できないだろう ユーザが勝手に作ったクラスとかどうするんだ
はいはーい hash計算関数を書かせればいいと思いまーす
>>271 それは std::map に
任意の型のキーに対して比較演算できないだろう
ユーザが勝手に作ったクラスとかどうするんだ
って言うようなもんだぜ。
>>273 std::map はコンストラクタで比較用の関数オブジェクトを指定する仕様だから、それを使うに決まっている
ADLを利用してoperator>を定義してやるだけでおkじゃなかったっけ
デフォルト引数で std::less<Key> が指定されてるから、デフォルトのまま使う場合は operator< でおk
277 :
273 :2007/10/12(金) 12:56:43
>>274-276 それは知ってる。
hash 関数も同じようにできるから
>>271 はおかしいって話。
デフォルトの less みたいなのが決められないってのが、かつて
規格に含まれなかった理由かな?
std::map<int, hoge> keyがintでもhash値計算し直すの?
unorderd_mapの実装だとどうなってる?
>>279 クラステンプレート std::hash が標準で提供されて、デフォルトだとそれ使う。
20.5.15 Class template hash [unord.hash]
1 The unordered associative containers defined in clause 23.4 use specializations of hash as the default hash function.
This class template is only required to be instantiable for integer types (3.9.1), floating point types (3.9.1), pointer
types (8.3.1), and std::string, std::u16string, std::u32string, and std::wstring.
どんなクラスでも挽き肉にしちまえば同じ型?
std::hash の戻り値は sttd::size_t 。
実態はメモリ上に格納するから、size_tってのは妥当だな。
std::size_tを使うと intの値に変換するときにコンパイラに怒られるのが嫌
>>284 そういう使い方して良いのかな?
わざわざ怒られるくらいだからしない方が良い?
でも外部のライブラリなんかがintを要求するのはよくあること。
ま、外部のライブラリが時代遅れっつうことで我慢だ コンパイラに怒られることが問題なんじゃあない
怒られるのが嫌なら明示的にキャストすればいい
Cスタイルのキャストはあまり使いたくないんだがこういう時ぐらいは許してもらえるかな…
>>289 static_cast で十分だろ。許さない。
ライブラリによっては非constポインタを要求してくるから、 static_castだけでは不十分だ。
>>291 いつの間にポインタの話に・・・まあいいけど。
可能ならローカルなコピーを渡せ。それがダメなら const_cast しろ。
Cスタイルキャストは許さない。
293 :
291 :2007/10/13(土) 19:33:43
>>292 ごめん、286が「外部のライブラリ」とか言ってるから
ライブラリにデータを渡す際に必要になるキャスト全般の話をしているのかと…
関数型キャストは……ポインタには使えないか。
unionでおk
reinterpret_cast + const_castコンボとかだと流石にげんなりするな
イテレータの名前をいつも迷うんだけど みんなはどういう名前にしてる?
i j k
面倒なんでBOOST_TYPEOFを使っちゃってます
it,jt,ktの俺は異端
俺は iterator i, iterator j, iterator k という風に心の中で読んでおいて、その実体は ii, ij, ik でも k までネスト構造を作るのは気持ち悪いから実際には j までしか行かないな、関係ないけど。
リストのときはit_l ベクタのときはit_v ってやってた
>>297 変数名は使用目的に合わせてつけろよ。型じゃなくてさ。
単純なループ用なら int i, j, k, ... でいいけど。
itereetaa
native typeofだと登録なしで使えるってその登録じゃないか
とあるクラスfooへのポインタを格納するリストのmylistがあるとします。 このリストから、foo::isInvalidがTRUEの要素だけを削除したいと思います。 次のように実装してみたのですが、クラッシュしてしまいます。 std::list<foo*>::iterator it; for(it = mylist.begin() ; it != mylist.end() ; ++it) { foo * p = (foo *)(*it); if(p->isInvalid) { mylist.erase(it); delete p; continue; } } そこでmylist.erase()したら、itをmylist.begin()で初期化するようにしたところ クラッシュしなくなりました。 もしかしてリストから要素をeraseすると、イテレータは無効になるのでしょうか?
309 :
デフォルトの名無しさん :2007/10/14(日) 17:54:22
erase()の戻りがiteratorなのはなんでだと思う?
>>308 > もしかしてリストから要素をeraseすると、イテレータは無効になるのでしょうか?
あたりまえだろ。
>>309-310 あ、なるほど。。戻り値が新しい有効なイテレータなんですね。。
勉強になりました。ありがとうございます。
>>308 std::list::remove_if() 使えば?
これぐらいなら標準のファンクタでいけるだろ。
313 :
312 :2007/10/14(日) 18:01:46
あ、ごめん。 delete p が要るのか。標準のやつだけじゃ面倒だな。
> itをmylist.begin()で初期化 典型的O(n^2)処理にワロタ
315 :
308 :2007/10/14(日) 18:02:41
308です。するとこんな風に書けばいいのでしょうか? std::list<foo*>::iterator it; for(it = mylist.begin() ; it != mylist.end() ; ++it) { foo * p = (foo *)(*it); if(p->isInvalid) { it = mylist.erase(it); delete p; if(it == mylist.end()) { break; } } } みなさんならどうしますか?
>>308 > foo * p = (foo *)(*it);
こういうキャストやめてくれよ。
サ、サイズが1なら問題ないもん!
>>315 なんでキャストが要るんだ?
まぁそれでいいと思うが、俺ならstd::list<boost::shared_ptr<foo> > にしてdeleteはしないな。
>>308 for(std::list<foo*>::iterator it = mylist.begin();
it != mylist.end();)
{
foo * p = *it;
if(p->isInvalid) {
mylist.erase(it++);
delete p;
} else {
it++;
}
}
これでどうよ。eraseがiteratorを返さないコンテナでもOK。
>>315 それだとinvalidなのが連続したときに二番目を逃すことになる
eraseしなかったときだけ++itするべし
>>319 なるほど。僕もそれで行くことにします。
>>320 あ、そうですね。。忘れてました。。
>>316 そうですよね。。でもそうしないとインテリセンスが反応してくれないのでつい。。
皆さんありがとうございました(^-^)
>>319 それvectorに適用しようとするとひどいことになるぞ
vectorの真ん中をeraseする奴なんているのか?
別におかしくないだろ
vectorなんてクソ vectorなんてクソ vectorなんてクソ
STLって流行ってる? うちの職場だと使ってるやつ数人だよ 存在も知らないやつも多い気がする うちがレベル低いだけですかそうですか
わかってるじゃない。
330 :
デフォルトの名無しさん :2007/10/15(月) 01:00:57
レベル低い
>>328 もう流行るとかいう段階を越えて、常識と化している。
・・・はずなんだけど、そういう職場の例はしょっちゅう出てくるね。
流行る 流行らない という性質のものじゃない気が
>>297 iter
ite
it
i
ネストが深くなるにつれて名前が短くなる
itr itr_end itr_i itr_j itr_k .... の俺は少数派ですか?
>>333 4段以上のときはどうするの?
逆にした方が文字数でネストの深さがすぐに分かって良いかもね
iteratoooooor
Effective STLって役立つね 読んでるやついる? つーか常識?
workaround的なものが多くてなんだかなーって
stl::listのpop_front()について質問です。 double_freeで落ちてしまったので、いろいろ調べ始めたのですが 要素数がないときはどのような動作をするものなのでしょうか? 環境によって動作が変わったりするものなのでしょうか? 要素数チェックを含んでいるかどうかを調べようと思ったのですが これといったドキュメントを見つけられませんでした。
規格にはa.pop_front()はa.erase(a.begin())と同じだと定義されている。 で、eraseについては、「有効な」イテレータqに対して、a.erase(q)の意味が定められてる。 aが空の時はa.begin()は有効なイテレータを返さないから、a.pop_front()の意味は規定されてないことになる。
やはりキチンと要素数チェックをすべきということですね。 ありがとうございました。
std::string で reserve() メソッドを呼び出したとき, 要求したメモリを確保できなければ例外が発生するのですか?
>>343 すんまそん、なんつー例外が発生するんでしょうか?
std::runtime_error の派生クラスだと思うんですが・・
valarrayにswapとassignはないの?
valarrayはSTLじゃない
valarrayとbitsetは見なかったという事でひとつ・・
でもvector<bool>はSTLだよね…
コンテナかどうか議論するならまだしもSTLではないと言うのは意味不明
vector<bool>はSTLのコンテナの要件を満たしてないけどね
vector<bool>特殊化はいつ抹殺されるの?
このスレの名前自体が以下略
いや、C++の標準ライブラリの一部を漠然と括るには便利な名前じゃん 明確な定義がない以上どこまでがSTLかの境界を定めようとするのが不毛ってだけで
使うと初心者離れしたような錯覚を起こす例のライブラリ群 だよね!
boostのことか
まあ、boostも着々と標準に取り込まれつつあるようだし いずれboostがSTLの範疇になるの日がくる……かも
標準ライブラリって作られたときは歴史が浅いからマズイ仕様がおおいよな。
boostは敷居が高すぎるな エラーが出ると何がなんだかさっぱり解らん
凝りすぎのライブラリは大抵糞
boostヘッダが長くて萎える
初心者だけどboost使ってすみません でもboostからC++に入ったのでやめられません
道具なんだから使いたいときに使えばいいだけ
美人は三日で飽きる Boostは三日で慣れる
bootsは三日で臭くなる
valarray … MTLとかのライブラリの登場でお払い箱 … bitset … 何それ?(固定長ならビットフィールドで十分)
>>367 C++0xの新機能を使って書き直して
リニューアル/パワーアップするとかないのかな…
ないでしょう。valarrayはインターフェースがダメ
VC80のmapのメモリ配置がvectorみたいに連続しているんですが、 やはりvectorがそうであるように挿入を繰り返すと大量の領域があらかじめ確保されてしまうんでしょうか。 1万件を超える数の要素を操作するから利用を躊躇う。
連続してたらmapの意味無いじゃん
>>370 想像で「躊躇う」とか言ってないで、自分のケースで実際にまずいかどうかは
実測して判断したら?
まずいようなら、Berkeley DBのようなものを使えばいいでしょ
vector<int> result; resultを戻り値にしたいのですが、プロトタイプは、どのように宣言したらいいですか
374 :
デフォルトの名無しさん :2007/10/21(日) 17:48:41
日本語でok
>>373 vector<int> foo();
375 :
デフォルトの名無しさん :2007/10/21(日) 17:52:38
>C++標準ライブラリの一つ とあるけど、ほかの標準ライブラリってたとえば何があるの?
>>375 Cから引き継いだライブラリとかじゃね?
>>376 広い意味ではC++のライブラリに含めるかもだけど
普通はCのライブラリだから 標準とはちっと違う気がします
>>374 日本語理解してくれてありがd
ほんまやね、適当に関数定義と宣言してもコンパイラ通りますやん
vector<int> foo();
vector<int> foo()
{
vector<int> result;
return result;
}
379 :
デフォルトの名無しさん :2007/10/21(日) 18:10:39
>>378 なにが疑問なのかさっぱりわからんが、コピーを戻していることを忘れるなよ。
vector<int>* foo();
とか
boost::shared_ptr<vector<int> > foo();
とできないか、よく考えとけ。
>>375 IOストリームはSTLじゃない。stringもSTLコンテナとして使えるがSTLではない。
C++固有のライブラリならこのくらいかな…?
標準例外クラスもかな?
delete reinterpret_cast<std::vector<int>*>(
>>381 );
これくらいで切れ気味って認識なら完全に切れてるやつで溢れてるなりよ
2chは口が悪いのがデフォみたいなもんだからなあ。
口調の問題じゃなくて、有無を言わせない一方的な書き方で、 特定の選択肢を押し付けようと必死になってるように見える まあつまらんことだが
「コピーを戻している」と説明があるが?
>>386 >>378 でも
>>379 でもないが、俺もvector<>のコピーを戻すという設計は
正直コスト的に気になる。
>>379 は(口は悪いが)それを親切に指摘しているだけに見えるよ。
まあ俺ならまっさきに考えるのは、古き良き引数での参照渡しだけれども。
389 :
374=379 :2007/10/21(日) 18:49:20
>>386 >>373 さんが、どのような業務でこのコードをご利用になるのか、わたくしには推測できかねますので、的外れなご提案になっておりましたら
平にお詫び申し上げますが、
>>378 のコードでは、return result; を行う再に、ベクターの全要素がベクターのコピーコンストラクタによって
コピーされる処理が発生するおそれがあります。もちろん、コンパイラの戻り値最適化によってコピーがおこらないケースもありますが、必ず
そのことが保証されているわけではございません。もし、intのベクターに格納されている要素数が多い場合ですとか、ベクターに格納するのが
intではなく大きな構造体である場合、このことは性能上の大きな問題になることがございます。そこで、vector<int>* foo(); のように、foo()
の中でベクターをnewし、そのポインタを呼び側に戻すようにする設計を採用されますと、要素数が多い場合、一要素のサイズが大きい場合で
も、コピーの時間的コストの問題を回避することが可能でございます。また、現代ですと生のポインタでは無く、スマートポインタというもの
を用いることも可能でございます。その場合の関数シグネチャは、boost::shared_ptr<std::vector<int> > foo(); のようになるはずでござい
ます。残念ながら、ブーストやスマートポインタについてここで詳細にご説明差し上げることは困難ですので、御自分でググレカス
とでも書けと? 毎回こんなん書くほどひまじゃねーよw
#あ、RVOに触れたから
>>379 より親切になっちゃったw
あらら切れちゃったw
392 :
386 :2007/10/21(日) 18:57:43
>>388 確かにコピーはコストが高いけど、無条件で避けるのが良いとは思わないな
頻繁に呼ばれない、かつ、返されるvectorがあまり大きくないことが分かっている関数なら、
コードの簡潔さのために値で返すのがよいと思う
モジュールの内部でのみ使う便利関数なら、とりあえず値で返しておいて、
コストが問題になるようなら別の方法に切り替えることもできるし
>>389 丁寧に書けなんて一言も言ってない
俺なら選択肢を提示するにとどめるので、「…できないか、よく考えとけ」という姿勢が
ちょっと気になっただけだ
あと、俺は
>>381 じゃないので、念のため
もしくは参照渡しで格納場所を関数に渡してしまうという手もあるけれど…
事実として、
・
>>379 は、元質問者が気づいていないかもしれない「コピーのコストの存在」と「避けかた」を示している。これはまさに
>>392 でいう選択肢の提示だ。
・ 一方、
>>386 は、選択肢の批判をするだけで、新しい情報の提供や、新しい選択肢は提示していない。これは典型的な煽り。
さて、どっちが有益?
>>392 でようやく新しい情報の提示をしたのは評価するが。
よくあるstringみたいに、コピーのコストがポインタ1-2個分しかないvectorって作れないんだっけ?
>>395 std::auto_ptr<std::vector<T> >
それは379他でガイシュツなので、vector単体でそういう実装ができるかどうかをキボン
>>397 素直にコピーする vector の実装を vector_impl として、 shared_ptr<vecotr_impl> を
ラップする実装をコピーの軽い vector とすれば可能。
そういう実装を採用しているSTLってありますか?
>>398
>>400 コピーのコストを優先すると何を捨てることになるんだろう。ちょっと考えてみる。トンクス。
全てを参照でもちまわるという発想は実はGC型の(つまり、多くの) オブジェクト指向言語と同じだ GCの代わりをshared_ptrでやろうってこったな 循環参照には無力だが コピーを安価にするためにはコピーオンライトというテクニックが伝統的に 使われているが、マルチスレッド環境では正直微妙で、下手に使うと 弊害のが多いかもしれん。
>>379 です
皆さんいじってくれておおきにww
全然切れてナイッスヨww
STLの参照渡しは最近のお気に入りで乱用しているんだけど
(便利がいいですよね、巨大コンテナも楽々動作してる感じ)
実は、相関関数のクラスライブラリィがどうしても必要になって、
一月程前、STLを覚え始めた頃に作ったコマンドラインで動作する
相関関数のプログラムのコードをいじくりまわしていたら、当事は参照渡しが
使えなかったので、ベクトルをprivateで宣言して、クラス内で可視できるように、
まぁまぁ巧く実装してあったんだけど(自画自賛ww)
ふと、参照渡しができるのなら、参照返しも出来る悪寒がしたので、
あまり期待してなかったんだけど、ここで尋ねてみたってかんじです。
>>402 std::stringはCoWが多いようだね。
>>392 のまとめ:
コピーのコストが安いことがあるのを忘れるなよ。コードの簡潔さのために
vector<int> foo();
とできないか、よく考えとけ。
感想: 392の「よいと思う」と379の「よく考えとけ」の違いがわからん。俺なら選択肢を提示するにとどめ、「よいと思う」などとは書かない。それと値で戻すコードが簡潔だと考えるのは392の主観で、押し付けがましい。
>>403 よし、次はこれだな。と釣ってみる。
vector<int>& foo()
{
vector<int> result;
return result;
}
>>402 >>404 まえつかってたSTLのstringは、x86むけにしかスレッドの排他制御のコードがはいってなくて、AMD64でそれを使って盛大にあぼーんした。
402のいうマルチスレッドだと微妙、というのは排他制御のコストの話かもしれないけど。
>>379 です
イテレータで返す方法とかもありだな
408 :
379 :2007/10/21(日) 20:01:20
スマソ
>>378 でした
ってゆうかイテレータで返す方がつぶしが利きそうだな
>>405 ローカル変数の参照、ポインタは返しちゃいかんでしょ。
関数抜けたら変数なくなってる。
>>409 ですが、まだ初めて一ヶ月くらいなんで間違ってるかもしれんが
vector<string>を引数で渡す場合でこんな感じかな
template<typename Iter>
void sub(Iter first, Iter last) {
string foo;
while ( first != last ) {
foo = *first++;
...
}
}
vector<string> vs;
list<string> ls;
string as[5];
sub(vs.begin(), vs.end());
sub(ls.begin(), ls.end());
sub(as, as+5);
>401 copy-on-write するなら実体を共有してるうちのどれかに書き込みが発生したときに vector 全体のコピーをしなければならない。 ということで、要素に対する参照や末尾に対する追加が constant time にならず標準の要求を満たさないと思う。 >404 最近は >402 の如く排他制御のコストが高いってんで CoW は避ける方向だと思う。
>>412 それは「イテレータで返す」とはいわないだろう。。。。。。
「イテレータを渡す」というような。
日本語nativeじゃないとかだったらゴメンだけど。
415 :
デフォルトの名無しさん :2007/10/21(日) 20:42:46
>>413 ありがとう。
ということは、最近は std::string foo(); もそれなりにコストかかるんだね。
vector<int>をリターンする代わりにiteratorを使うんなら 引数は出力イテレータ一個でいいな。で、 vector<int> vec; foo(back_inserter(vec)); とかやる。
そろそろ右辺値参照という今すぐ使えないものをねだってみる。
>>417 彼は特殊だから。。。もちろんいい意味で。
>>413 その理屈でいくと、 string を copy-on-write で実装するのも不味くないか?
string には計算量の制約が無いんだっけ?
421 :
デフォルトの名無しさん :2007/10/21(日) 22:33:49
libstdc++の.tcccファイルって何? なんで.hと分離してんの?
422 :
デフォルトの名無しさん :2007/10/21(日) 22:58:19
>>413 今Fedora(Linux)のlibstdc++-4.1.2を見てみたが、refcountされてる。
>>417 怪しいoven君キタ━━━━━━(゚∀゚)━━━━━━ !!!!!
そんなにrangeっていいのだろうか 必要性を見出せないのは俺があんまり複雑な事をやってないからかな
425 :
デフォルトの名無しさん :2007/10/21(日) 23:22:10
いまぱっとしらべた感じだと、 - VC7以降と最近のSTLPortは単純コピー、スレッドセーフ - g++3/4(libstdc++)は参照カウント、スレッドセーフティーは怪しい、たぶんアンセーフ - BCCも参照カウント、スレッドセーフティは不明 みたいだな。More Exceptional C++になんか書いてあるらしいが持ってない。amazon.comに注文かけた。
rangeでpush_backしてもらうように書けたっけ? まぁpair<iteratoriterator>がコンテナ風味に使えるのは便利だはな
>>425 >たぶんアンセーフ
ソース見たら、_Atomic_Word 使ってなんか操作してるな。大丈夫かも。よくわかんね。
>>424 BOOST_FOREACHなんてどうよ?
あとはrange_ex使えば、アルゴリズム関数の引数で、
c.begin(), c.end()としていたところを
単にcとすればよくなることとか。
>>424 rangeがあれば
auto rng = transformed(sorted(filtered(
equal_range(c, "foo"), identity()), converter<T>());
vector<T> v(rng); // ここで初めて計算
みたいなことが余分な作業領域とコピー無しでできるよ
また怪しげなpsendo
最近boost触り始めたんだけど、boostの事をぐぐるとちらほら見かける"oven"ってなに?
オーブンレンジ
一行野郎と相性がよさそうだな
>oven rangeに対応したアルゴリズムライブラリでなかったか? range≒レンガからか…無茶か…
煉瓦?
オーブンレンジだろ、常考
eggとかもあるね、そういえば
boost vaultとか覗くと俺の欲しいものの9割ぐらいが既により高い完成度で提供されてて笑える これフルに利用したらC++でもLL言語とか使うより手早くソフト作れるんじゃね?
お前がやればな
>>440 そういう現実をみせつけられると生きている意義が見いだせないよな。
まぁ、俺もゼミで毎週言われていることだが。
monthという配列の要素は月を表します、月変りが発生した要素の番号を取得するのにSTL的にははどうしたらいいですか 例えば int month = [10, 10, 11, 11, 11, 12, 12, 1]; の場合 3,6,8が求めたい
それはSTLと関係あるのだろうか?
そういうアルゴリズムが用意されていますか? ってことじゃね? 俺なら普通にイテレータで舐めるなぁ。
うー、なんで2,5,7じゃないんだろ。
mismatchが使いたいなら使える。 # include <algorithm> # include <iostream> int main() { int v[] = {10, 10, 11, 11, 11, 12, 12, 1}; int *first = v, *last = v + (sizeof v / sizeof v[0]); while(first != last) { first = std::mismatch(first + 1, last, first).first; if(first != last) std::cout << first - v << "\n"; } }
>>448 サンクス
mismatchは二つのシーケンスが必要だと思っていたんですが、一つでも出来るんですね。
ところで後だしで申し訳ないですが、要素が年月日の場合同じく、月変りが発生した要素の番号を取得する場合は、どうしたらいいのか教えてもらえませんか
substrで月を切出していくと思うのですがどの様に使ったらいいのかわかんないんで・・・・・
int v[] = {20071001, 20071002, 20071103, 20071120, 20071122, 20071201, 20071208, 20080105};
>>449 template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred);
ここは adjacent_find() の出番だろ。
>>449 int に substr() じゃ、どの様に使ったらいいかわからんわな。
v の要素が string のつもりなら substr() して atoi() しとけばいいでしょ。
既出だったらスマヌ。 コンパイルは通るけど、例外で死ぬ〜…(VC7) list<foo *> fooList;// <- 多態性を持たせるためポインタです /* なんかいろいろ */ for(list<foo *>::iterator fooIt = fooList.begin(); fooIt != fooList.end(); ++fooIt) { (*(fooList.begin()))->hoge(); //意味はないけどOK (*fooIt)->hoge(); //NG...orz (ポインタが取れていないらしい...) }
((foo *)*fooIt)->hoge();
>>453 おかしいようには見えない。
何か別のところで変なことしてるんじゃないか?
例えばこれなら正しく実行できると思う。
# include <list>
# include <iostream>
using namespace std;
struct foo { virtual void hoge() = 0; ~foo(){} };
struct bar : foo { void hoge() { cout << "bar::hoge\n"; }};
struct baz : foo { void hoge() { cout << "baz::hoge\n"; }};
int main()
{
list<foo *> fooList;
fooList.push_back(new bar);
fooList.push_back(new baz);
fooList.push_back(new bar);
for(list<foo *>::iterator fooIt = fooList.begin(); fooIt != fooList.end(); ++fooIt)
(*fooIt)->hoge();
}
>>454 そのキャストは無意味だろ。
456 :
453 :2007/10/24(水) 14:20:29
解決しました〜お騒がせしやした。 fooList = getFooList(); な部分があったので、 list<foo *> getFooList(); ↓ list<foo *>& getFooList(); で普通に通るようになりましたとさ。 …理由は究明中ってことで。
(**fooIt).hoge();
458 :
453 :2007/10/24(水) 22:03:44
誤りがあったので訂正…
このように省略していたのをちゃんと書けば普通に動きました。
>>456 のような対処は必要ないです。
…違う意味になるってことか?
[誤]
for(list<foo *>::iterator fooIt = (getFooList()).begin(); fooIt != (getFooList()).end(); ++fooIt)
{
(*fooIt)->hoge(); //NG...orz
}
↓↓↓
[正]
list<foo *> fooIt getFooList();
for(list<foo *>::iterator fooIt = fooList.begin(); fooIt != fooList.end(); ++fooIt)
{
(*fooIt)->hoge(); //OK
}
>>458 fooIt = getFooList().begin()と書くと、getFooListが呼ばれ、その結果が一時オブジェクトにコピーされ、
その一時オブジェクトに対してbeginが呼ばれ、その結果がfooItに格納され、一時オブジェクトが破棄される。
この時点でfooItの指す先は既に破壊されているので、fooItは無効なイテレータ。
さらにfooIt != getFooList().end()とすると、また別の一時オブジェクトが作られて、
そのendとfooItが比較されるわけで、当然まともに動かない。
>420
> 14882:2003 23.1.2 / 12
>Table 68 lists sequence operations that are provided for some types of sequential containers but not
> others. An implementation shall provide these operations for all container types shown in the ‘‘container’’
> column, and shall implement them so as to take amortized constant time.
で、Table 68 に operator[] があるけど、string は書かれていないのでこの制約にかからない。
insert() とか Table 67 にあるものは、コンテナ依存なんだけど、vector については 23.2.4 / 1 他に記述がある。
後、iterator の無効化についても規格の記述を満たさなくなると思うけど、こっちは string 自体にも指摘がある。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#263 将来的には string は seqence container ではない、という扱いになるっぽい。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#718
461 :
453 :2007/10/25(木) 08:57:44
>>459 理屈もわかってすっきりです。
ありがとうございました。
462 :
デフォルトの名無しさん :2007/10/26(金) 08:00:35
質問です。multimapを使って「ある部屋に入ってきた人数(double)」と「最初の人が入ってから現在までの経過した時間(int)」と 「その人達が動き出す未来の時間(int)」を記録してmultimapに格納したいと思っています。それで普通は #include <map> typedef std::multimap< int, double, std::less< int > > Mmid; : Mmid pairs; cout << "\nNode Multimap pairs contains:\nKey\tValue\n"; for( Mmid::const_iterator iter = pairs.begin(); iter != pairs.end(); ++iter ) cout << iter->first << '\t' << iter->second << '\n'; とやるところを typedef std::multimap< int, int, double, std::less< int > > MmidX; //宣言はビルド通ります MmidX trios; //←ここで定義するとエラーが出ます とやったら /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_multimap.h: In instantiation of ‘std::multimap<int, int, double, std::less<int> >’: edge.h:49: instantiated from here /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_multimap.h:118: error: no type named ‘value_type’ in ‘struct std::less<int>’ : /usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_multimap.h:170: error: using invalid field ‘std::multimap<_Key, _Tp, _Compare, _Alloc>::_M_t’ make: *** [edge.o] エラー 1 とエラーが出ます。 multimapってやっぱりキーともう一つ対になる値の二つしか保持できないんですか? もし、そうだとしたら他に何か良い案はありませんか?
こうか? std::multimap<int, std::pair<int, double>, std::less<int> > 何をしたいのかよくわからんが。
ある部屋をキーにして、複数の値を格納したい。 ある部屋をキーにすると、Mapでは1つしか格納できないからMultiMap<これが間違い MultiMapなら引数をたくさん取れる<これも間違い 素直にstructとmapで実装したほうが早いかと。 てか、multimapの仕様書ちゃんと見たら? STL解説ページでもいいけど。 struct room { double a; int b; int c; } typedef multimap< int, room > d;
そこで boost::tuple ですよ。
なんか Boost スレがおかしなことになってるね
まず、人数がdobuleなのが不可解。 深遠な理由があるのかも知れないが。
すまん、doubleね。
long や longlong 以上の桁の数字が入るが 下の方の桁の正確さは求められていないっつーことか じゃ最初から 1/1000 とか 1/10000 とかで int にした方がいいね
long long以上の人数って…
アカシックレコードでも作ってるのかもしれん
過去に死んだひとと同じIDをあとから生まれたひとに振ると問題あるだろ 2000年問題の騒ぎどころじゃなくなる
誤差ありで厳密に比較できないIDって何だそら
doubleはただのホルダで long longが使えない環境のために64bit整数を保持しているのかも知れん。
int_64t とかじゃだめなん?
476 :
462 :2007/10/28(日) 07:26:22
大変長らくお待たせしました。
>>464 さんの方法を読んで一時間くらいでなんとか出来ました。
これは便利ですね。いくらでも送りたい放題じゃないですか。
実はキーは「その人達が動き出す未来の時間(int)」でしたので
構造体の中の要素は二つで済みました。
>>467-
>>475 そこまで深遠な理由はありませんよ。w
人数がdoubleなのは確率に基づいて計算するからなのです。
ですから、「部屋@から部屋Bへ9.844人が移動」とかあり得ます。
見た目は簡単そうな式なのですが、プログラムにすると大変ですね。
それでSTLのお世話になったのですが、
皆さんのお陰でSTLの問題は解決しましたので
後は送った値をどう処理するかですね。
うまくいくといいんですが…。
これからも度々お世話になると思います。
皆さん、どうもありがとうございました。
そんなことしたらキーが一致しないかも知れない心配をしないといけないぞ
現在の高校3年以下の人間は中学でイオンや三角関数を学ぶ時代まで遡るべき。
あれ?今は習わないの? 三角関数のテイラー展開くらいまでは高校で習ったが・・・ しかし厳密な収束性とか大学に入るまで 一切気にしてなかったのは秘密だ。
>>479 旧過程と新過程の試験問題比べれば分かる、センターと一次試験?
481 :
462 :2007/10/28(日) 21:09:40
>>477 キーは「その人達が動き出す未来の時間(int)」ですので大丈夫じゃないですか?
そういう意味ではなくてですか?
482 :
デフォルトの名無しさん :2007/10/29(月) 03:48:06
setつかうよりmapのほうが良いんですか? setのみで済むときでも順番にキー付けておけば配列のように使えますから setのほうが速いとかすぐれている点はありますか?
>順番にキー付けておけば配列のように よくわからん どういう使い方?
484 :
482 :2007/10/29(月) 04:03:42
#include <map> #include <string> #include <iostream> using namespace std; typedef map<int, string> Set; main(){ Set x; x.insert( Set::value_type( 3, "日本" ) ); x.insert( Set::value_type( 1, "日本語化" ) ); x.insert( Set::value_type( 2, "入門" ) ); x.insert( Set::value_type( 0, "ニュース関連" ) ); x[1] = "ニュークリアス"; cout << x[0] << endl; cout << x[1] << endl; cout << x[2] << endl; cout << x[3] << endl; }
485 :
482 :2007/10/29(月) 04:05:49
でも、キーでソートしてしまうから、右側の"日本"だけのソートとは別ですね
486 :
デフォルトの名無しさん :2007/10/29(月) 04:28:11
検索した物が何番目か調べるのはこういう風にやれば良いんですか? #include <set> #include <string> #include <iostream> using namespace std; main(){ set<string> x; x.insert("入門" ); x.insert("ニュークリアス" ); x.insert("ニュース関連" ); set<string>::iterator p = x.begin(); while( p != x.end() ){ cout << *p << endl; p++;} p=x.find("入門"); cout<<endl<<&p-&x.begin(); }
487 :
デフォルトの名無しさん :2007/10/29(月) 04:35:39
これ固まるんですけどわかりますか? #include <set> #include <string> #include <iostream> using namespace std; main(){ set<string> x; x.insert("入門" ); x.insert("ニュークリアス" ); x.insert("ニュース関連" ); set<string>::iterator p,q=x.begin(); p=x.find("入門"); cout << (int)distance( p, q ); }
488 :
デフォルトの名無しさん :2007/10/29(月) 04:47:53
おなじですけどこれ動かない理由わかりますか? #include <set> #include <string> #include <iostream> using namespace std; main(){ set<string> x; x.insert("1" ); x.insert("2" ); x.insert("3" ); cout << (int)distance(x.end(),x.begin()); }
489 :
デフォルトの名無しさん :2007/10/29(月) 04:49:10
わかりました 値がマイナスになると固まるようです cout << (int)distance(x.begin(),x.end());
>>486 いいえ。
>>487 q が未初期化だから何がおきても不思議じゃない。
>>488 distance() の第1引数は第2引数へ到達可能でなければならないが、
end() は begin() へ到達可能ではないから。
>>489 値がマイナスになっていたわけじゃない。
>>490 487 の q は初期化されてるだろ。
493 :
デフォルトの名無しさん :2007/10/29(月) 08:55:24
>cout << (int)distance( p, q ); pとqの位置をひっくり返せばいいんじゃないかな。 #include <set> #include <string> #include <algorithm> #include <iostream> using namespace std; int main() { set<string> x; x.insert("C++" ); x.insert("STL" ); x.insert("BOOST" ); set<string>::iterator p, q = x.begin(); p=x.find("STL"); cout << (int)distance( q, p ) << endl; return 0; } これで動いたよ。俺の環境では2バイト文字使うの面倒だからちょっと変更したけど。
494 :
デフォルトの名無しさん :2007/10/29(月) 08:58:51
> This function returns the distance between two iterators by determining how many times > the first iterator would need to be incremented until it was equal to the last iterator. 忘れてならないのは、この"incremented"ってとこですかね。
STLの各アルゴリズムはSSEを使うようには最適化されていないのでしょうか?
>>495 コンパイラとライブラリ実装による。
ヘッダファイルに定義があるだろうから読んでみればわかるかもしれない。
mapってアイテムinsertしていくとどっかでvectorみたいに領域確保しなおしでアドレス変わったりしますか? mapの中身を指してるポインタを外部に持ってるんですけど、こういうのって良くないんでしたっけか。
>>495 SSEを使うかどうかはアルゴリズムの問題じゃなくてコンパイラとコンパイルオプションの問題だろ。
>>497 その操作でイテレータが変わらないのは仕様にあったと思う。
ポインタにまで言及しているかは知らない。
valarrayなんかはSSEで最適化してくれないと存在意味ないと思う
>>497 map, set, multimap, multiset のイテレータおよび参照はコンテナから削除されるまで有効。
23.1.2p8
> The insert members shall not affect the validity of iterators and references to the container, and the erase
> members shall invalidate only iterators and references to the erased elements.
503 :
497 :2007/10/30(火) 12:23:11
accumulateの第三引数ってなに?
初期値
vector で、iterの示す位置indexを得る簡単な方法はあるでしょうか?
>>506 そのイテレータの対象となるヴェクタのビギンとの差でいいじゃん。
>>506 std::distance( vector.begin(), iterator );
509 :
506 :2007/11/01(木) 12:56:21
>>507-508 早速どうもです。
なるほろ、vectorはメモリ順序保証なんですね。
これでやってみます。有難う御座いました。
x ビギン o ヴィギン
>>511 beginのどこをどう読んだらヴィギンに?
513 :
デフォルトの名無しさん :2007/11/01(木) 13:38:43
沖縄の風を感じたので
energyをわざわざ「エナズィー」をカッコつけて歌ってる歌があったなぁ。
有料ゴミのレディオ
スィークゥワーサァー
517 :
デフォルトの名無しさん :2007/11/01(木) 17:42:22
518 :
517 :2007/11/01(木) 17:52:28
windwosXPでサブディレクリまで文字を正規置換するいいソフトないのでつくろうとおもうけど
boostと
>>517 どっちがいい?
使いやすいほう
文字を正規置換って、ファイルやフォルダのリネームのことか? Flexible Renamerで十分事足りてるんだが。
522 :
デフォルトの名無しさん :2007/11/01(木) 18:35:47
ファイル中身
523 :
デフォルトの名無しさん :2007/11/01(木) 21:18:29
524 :
523 :2007/11/01(木) 21:21:26
これだとだめです #include <iostream> #include <string> #include <fstream> using namespace std; main(){ string a,b; fstream fp("dd",ios::in); for(;;){ getline(fp, b);if(fp.eof())break; a=b.substr(0,2); b=b.substr(4,2); if(a!=b)cout<<a<<"\t"<<b<<"\n"; }}
526 :
523 :2007/11/01(木) 21:29:19
527 :
523 :2007/11/01(木) 21:35:05
できました
普通にUTF8をパースすればいいんじゃね ていうかスレ違いじゃね
530 :
デフォルトの名無しさん :2007/11/01(木) 22:23:10
stringで全角1文字が2バイトではないみたいなんですけど1文字取得したいときはどうすればいいですか
そういうのはwchar_tに変換してからゆっくり調理してやれば、
532 :
デフォルトの名無しさん :2007/11/01(木) 22:36:38
533 :
462 :2007/11/03(土) 09:10:13
また、お世話になります。
>>462 です。
<multimap>のerase()の括弧の中に何を入れれば、一番最初かもしくは一番最後の要素が消せるのでしょうか?
数字を入れるとキーが消せるのは分かるのですが、IteratorのPositionで消す方法が分かりません。
エスパー能力が必要かもしれませんが、どうかプログラムの断片を診てやってください:
■ edge.h ■
#include <map>
typedef std::multimap< int, double, std::less< int > > Mmid;
struct TIMESTRUCT
{
int arrivalTime;// arrival time = day time
double avatar; // number of avatars in a bank
};
TIMESTRUCT timeCapsule;
Mmtc atTime; // declare the multimap atTime;
■ node.cpp ■
if (edge->sourceNode() == this) {
edge->timeCapsule.arrivalTime = dTime;
edge->timeCapsule.avatar = edge->_bank2;
edge->atTime.insert( Mmtc::value_type( dTime + edge->r(), edge->timeCapsule ) ); //挿入しています
}
Mmtc::const_reverse_iterator r_iter;
for( r_iter = edge->atTime.rbegin(); r_iter != edge->atTime.rend(); ++r_iter ) {
edge->xWander = dayTime - ( (r_iter->second.arrivalTime - 1) + edge->r() );
cout << r_iter->first << '\t' << r_iter->second.arrivalTime << "\t\t"
<< r_iter->second.avatar << "\t\t" << edge->xWander << "\n";
}
edge->atTime.erase(5); // 問題はこの括弧の中です;これだとキーが'5'の要素だけが消せます
edge->atTime.erase(r_iter.rend()); // コンパイルできません;mo matching
よろしくお願いします。
>>533 const_reverse_iteratorにrend()なんてメソッドがあるかよく調べるんだ
つーか、期待されるべきrend()は要素を指さないだろ。
つうかend()は無効なイテレータなんで渡しちゃだめ
537 :
462 :2007/11/03(土) 09:29:48
え、でも…
ttp://www14.atwiki.jp/yonecle/pages/13.html rend()
reverse_iterator rend();
const_reverse_iterator rend() const;
…コンテナの先頭を指す逆方向反復子を返す。
本当にこれだけじゃなくていろいろやってみたんですよ。
もうアイディアが尽きました。
●erase()
void erase( iterator i); ←これと
…iが指す要素を削除する。
void erase( iterator start ,iteraterend); ←これの意味が分かりません
…startからendまでの範囲の要素を削除する。
size_type erase( const key_type& k);
…コンテナからキーの値がkである要素を削除する。
・・・取り敢えず、r_iterは使いますよね?
538 :
462 :2007/11/03(土) 09:33:42
>>535-536 はっ!
そうでした!
でも'rbegin()'でもダメだったような気が・・・
それにしてもこれに関する例って
ただのひっっっっっとつもないんですよ・・・。
これだけ探してないとなるとびっくりしますよ。
あったら御一報願います。
rend()はイテレータが持ってるんじゃなくて、コンテナが持ってる edge->atTime.rend()
540 :
462 :2007/11/03(土) 09:41:17
>>539 はい、自分もここ
for( r_iter = edge->atTime.rbegin(); r_iter != edge->atTime.rend(); ++r_iter ) {
で使っています。
あっ!
もしかしてr_iterだけで良かったのかも!
edge->atTime.erase(r_iter); // ←現在指している要素
正解ですか?
それなら
r_iter = edge->atTime.rbegin();
ってやっておいて
edge->atTime.erase(r_iter);
なら最初の要素が
r_iter = edge->atTime.rend();
ってやっておいて
edge->atTime.erase(r_iter);
なら最後の要素が消せますよね?
541 :
462 :2007/11/03(土) 09:42:45
いかん。 r_iter = edge->atTime.rend(); ってやっておいて edge->atTime.erase(--r_iter); // ←落とし穴 なら最後の要素、ですね?
begin() 最初の要素 rbegin() 最後の要素
543 :
462 :2007/11/03(土) 09:53:52
>>542 はっ!
そうだったんですか!
C++の本の付録のページで勉強してますからね・・・。
また一つ賢くなりました。
皆さん、またまたご協力ありがとうございました!
>>543 ネット使えてるんならいくらでもSTL解説サイト見れるだろう
rbegin().base()
546 :
462 :2007/11/03(土) 10:14:50
>>544 はい、もういろいろ読みました。
http://www.sgi.com/tech/stl/ ←こことか
でも、何故か「辞書」みたいなのしか見つからないんですよね:
●erase()
void erase( iterator i);
void erase( iterator start ,iteraterend);
size_type erase( const key_type& k);
・・・何故にそんなにボトムアップなんだろうって思います。
英語の辞書を読んで英会話をマスターしているような気分です。
時々、STLってC++本体とは別物に思えます。
あ、もうこんな時間じゃないですか!
・・・では、寝ますです(^_^)/~
>>545 え、その.base()というのは何ですkZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
>546
>時々、STLってC++本体とは別物に思えます。
ライブラリなんだから、そのライブラリの「お約束」を知る必要があるのは当然。
>でも、何故か「辞書」みたいなのしか見つからないんですよね:
いくつかの基本的な概念さえ押さえておけば、後は「辞書」みたいものだけで事足りるから。
つまり(自覚してると思うけど)今足りないのは基本的な概念の把握。
これも割と辞書的ではあるけど
ttp://www005.upp.so-net.ne.jp/episteme/html/stlprog/ あたりを読んでみれば?
で、もうちょい概念を押さえたら EffectiveSTL を読んどくのがおすすめ。
例えば今回の件は、第 26 項、第 28 項を読めば解決するはずだ。
簡単に言えば、コンテナのメンバ関数には reverse_iteartor を渡せないので
base() を使って iterator に変換してやる必要がある。
ただしその際、(削除を行う場合には)位置の調整をしてやる必要があるため、
container.erase((++r_iter).base());
みたいにする必要がある。
なお、ループしてる際の erase には iterator の無効化という別の問題があるため
それにも注意が必要(EffectiveSTL 第 9 項参照)。
すいません、初歩の初歩かもしれないですが vectorやlistの要素へのポインタを持つ場合( p = vec[6]; とか p = &itLit ) このpがずっと安全にその要素をさしつづける保証はあるのでしょうか? ・当然元の vector や list が開放されればさせなくなるのはわかります ・たしか、vectorはpush_backしていくとメモリーの再確保が発生するので、要素の存在位置がかわるはず ・listは双方向リストだから大丈夫? ・mapのsecondとかは? firstはソートされるため変化しそう google
>>548 listとmap類は大丈夫。mapのfirstも。
ついでに言うと、mapはpair<key, value>を保持している訳だから、
firstが動いてsecondが動かないということはありえない。
ソートはポインタの付け替えでできる。
>548 >vectorやlistの要素へのポインタを持つ場合( p = vec[6]; とか p = &itLit ) どっちも要素へのポインタと思えないのが少し不安。
>>549 firstも大丈夫なんですか!?
どうやって二分探索してるんでしょうmapは・・・
ソートはポインタの付け替えでできる・・・?うーん、STLの本買うと面白そうですね
>>550 p=&vec[6]ですね。
p=itList
ですね。お恥ずかしい
mapは struct node { pair<const key_type, mapped_type> value; node* left; node* right; }; みたいな感じのノードを持ってて、挿入や削除があるたびに、 与えられた比較関数なりファンクタなりの結果をもとにleft, rightのアドレスを付け替えてるんだ。 valueはキーと値のセットなわけだから、secondが大丈夫なのにfirstがダメってことは無い。
俺はKeyへのポインタリストをもってて、ポインタリストは vector<void*> って感じにできてるんだと思ってたわ・・・ ちがかったのか・・・
その辺の設計思想は、typedefにも表れてるんじゃないかな。 vector<T>::value_typeはT、list<T>::value_typeもTだけど、 map<Key, T>は、Keyがkey_typeでTがmapped_type、肝心のvalue_typeはpair<const Key, T>だから。 つまり、pair<const Key, T>型こそが「mapの値」の地位にあるわけ。
STLの各種コンテナのend()が返す要素って中身をセットしても大丈夫なものなの? vectorはあからさまにだめそうだけど、setやlistあたりはNullObjectとして空の要素を確保してたりするのかな。 ↓こんな感じのことって有り? map<Key, Value> map_; map.end().second = Value(...); // キーが見つからないときのデフォルト値
いってことよ
プログラマに深夜も早朝もない
しかしなんだな、新しい言語を習得する時って俺の場合、良書が必要なのだが さっき『Effective C++第3版』と『Effective STL STLを使いこなす50の鉄則』を 書店で立ち読みしていて、どっちを買うか迷ったが結局両方買ってしまった しかしコンピュータ関連に限らないけど専門書って高いよね。 そこで問題です。 v1とv2という2つのvectorがあるとする。v1をv2の後ろ半分と同じ内容にする最も簡単な方法は何だろうか。 v2の要素数が奇数であるときに「半分」をどう定義するかは気にせずに、妥当な方法を考えてほしい。
// ??? std::vector<T>::size_type sz = v2.size()/2 v1.resize( v2.size() - sz ); std::copy_backward( v2.begin() + sz, v2.end(), v1.end() );
>>560 v1.assign(v2.begin() + v2.size() / 2, v2.end());
>>560 ふふふ さっそく(Effective STLを)つかっているな
>>560 です
>>562 最優秀賞を差し上げます。
560も『Effective STL STLを使いこなす50の鉄則』読んだのか、
因みに
>>561 の解答は明示的にループは使ってないから、一見効率よさそうに見えるが
std::copy_backwardの中でループ処理を行うのでassignより効率は悪い。
>>563 >>560 です
いい本ですねこの本、STL本で最初に買ったのが、ハーバート・シルトの
STL標準講座だったんだけど、基礎的な用法しか書いてなかった、
実用的なのはEffective STLのだね。
566 :
561 :2007/11/04(日) 13:14:19
oops
>>564 561 の効率が悪いのはループ云々じゃない。内部でループするかしないかって話なら
assign() でもしてるはず。
本質的な違いは、「デフォルト初期化+初期値代入」と「初期値で初期化」の違い。
569 :
462 :2007/11/06(火) 17:54:06
>>547 この短期間に二回も引越していてレスが出来ませんでした。あれから
r_iter = edge->atTime.rbegin(); // line 103
edge->atTime.erase((++r_iter).base()); // line 104
とやってみたのですが、以下のようなエラーが出ます:
node.cpp: In member function ‘void Node::backAndForth(int)’:
node.cpp:104: error: no matching function for call to ‘std::multimap<int, TIMESTRUCT, std::less<int>,
std::allocator<std::pair<const int, TIMESTRUCT> > >::
erase(std::_Rb_tree_const_iterator<std::pair<const int, TIMESTRUCT> >)’
以下略
make: *** [node.o] エラー 1
edge->atTime.erase(r_iter);でもほぼ同じエラーが出ます。
構造体を使ってしまったから普通の方法ではダメなのでしょうか?
>>569 エラーメッセージをよく見て。
atTime が const っぽい。
571 :
462 :2007/11/07(水) 07:33:48
毎度ありがとうございます。m(__)m
本からのコピペだったので無意識のうちにconst_reverse_iteratorを使っていました。
普段からconst付ける癖がないのでこういう目に遭うんですね、きっと。
今日は
>>535-536 さんの忠告が今頃になって役に立ちました。
結果が0にならないといけないところが1.2345678e-318みたいになっていて
KDevelopでデバッグしたところ、rend()の値をコピーしていたのが原因と分かりました。
忠告がなかったら今でもデバッグ中だったと思います。
更に精進致します。
もっと時間があれば本を読むんですけどね…
あ、前回、C++本の付録で勉強していると書きましたが、実際は24章あるうちの1章でした。
ま、STL本じゃないのは確かです。
オテレータ
vector の内容を ランダムに順番を変える方法はあるでしょうか? 逆順は reverse() で、できたのですが;
>>574 ありがとうございます。STL ってすごいですね。
自前で作るより、極力あったら使おうと思って、聞いてしまいました。
random_shuffleは厳密なランダムシャッフルではないから注意しる。 具体的には、random_shuffle前と全く同じ並びになることがない。 麻雀だのトランプだの選曲順だのならそれで問題ないとおもうが、 並び替える個数が少ない場合は問題になると思う。
>>576 まったく同じならびにならないという根拠をkwsk
少なくとも自分の環境のrandom_shuffleのコードでは、
そんなわけのわからん現象は発生しないかった。
GCC4で実験したが、同じ並びは発生した。 それよりも、第三引数を省略すると、結果が毎回一緒で使い物にならん。
>>576 それ VC6 の実装のバグじゃないの?
> 25.2.11 Random shuffle > Complexity: Exactly (last - first ) - 1 swaps. 要素数が2の場合、必ず交換されることにならないか?
同要素に対するswapが発生すれば良い
>581 >580 の URL にある「改善策」の swap 回数はそうなってる。
584 :
デフォルトの名無しさん :2007/11/17(土) 12:51:09
listに二分探査したらO(nlogn)な気がするんだけど、どうなんだろ? オーダー的には特化で線形探査でもしてくれたらいいんだけど、 微妙に意味が違うからやってくれなさそう。 そもそもlistで整列データ管理すんのがお門違いなんだけどw
なんだVCのバグか じゃあ安心して使えるな
>>584 イテレータのインクリメント・デクリメントが比較関数に対して無視できるほど軽いとすれば
O(log n) といえるんじゃないだろうか?
boostのドキュメント読んでよくでてくる ・Model ・Concept ・Refinement ってSGIのリファレンスに載ってるんでしょうか? なんかSTLを使うのに関してかなり重要な概念らしいんですが、全然意識してなかったので気になります
591 :
デフォルトの名無しさん :2007/11/18(日) 00:59:03
set
まず、vectorってcontentsのアドレスの連続性が規格で保証されてるんですよね? でもサイズとか増やせちゃうわけじゃないですか。 でメモリのアドレスが連続になるような確保って一括で確保しなきゃらならないですよね? と言うことはcapacityが変わる時って変化後の容量分一括確保してそこに変化前の値をコピーして元データを削除 とかやってるんでしょうか? なんかVCに付属のソース見ても何やってるのかいまいちわからないと言うか、 アンダースコアとかマクロだらけで読む気がなくなるというかで疑問のままなんです
vector の検索について質問です。 typedef pair<int,int> AA; vector<AA> v; にて、v要素の firstに対して検索したいのですが どのようにすれば良いでしょうか? find_if()を試してみたのですが、私の力ではpairの組みで一致 するところまでしか出来ませんでした。 p = find_if(v.begin(), v.end() , bind1st( equal_to<AA>(), AA(10,15) ) // 本当はsecond無視で first==10を見つけたい );
それpairでやる意味あるの? intふたつ持った構造体に比較関数定義した方がよくないか?
それはmapを使うところなんじゃないかな
{ typedef std::pair<int,int> AA; std::vector<AA> v; struct Comp { int m_i; Func(int i) : m_i(i) {} bool operator()(AA const& i) const { return i.second == m_i; } }; v.push_back(std::make_pair(10,15)); std::vector<AA>::iterator p = std::find_if(v.begin(), v.end(), Comp(15)); } STLの範囲で、boost::lambda使わなきゃこんな感じ?? 使えば次のようになる find_if(v.begin(), v.end(), bind(&AA::second, _1) == 15 );
599 :
595 :2007/11/20(火) 19:49:48
早速有難う御座います。
>>596-597 リスト位置と内容、この3つの値を使うリストということで
ご了解いただければ。
>>598 なるほど。比較構造体を作るわけですか。
参考にさせていただきます。有難う御座いました。
キリ番取らせたら日本一の俺様が
>>600 を戴きます
比較構造体?
>>599 比較構造体ではなく関数オブジェクト、もしくはFunctorと言え。
ふぁんくた!
struct comp →直訳=比較構造体
略して strcmp
そういうことか!
初めて知った
メモメモ
struct -ing →string
struct -ip →strip
ドラエモン マイナス エモン プラス ムカン を思い出したが、たぶん知ってる奴はあまり居ない
フク マイナス ク プラス ロ
おまんじゅう マイナス じゅう プラス た
もういいでしょ
教えてください class Foo { vector<string> vec; //これはOK vector<string> vec(5); // error C2059: 構文エラー : '定数' public: Foo(); ~Foo(); }; クラスのメンバ変数に固定長のコンテナを作るとエラーになるのはなんで?
C2059: 低脳エラーです。今すぐC++はやめて下等な言語を使用してください。
>>618 初期化はそんなところに書けない
コンストラクタに書く
Foo::Foo() : vec(5)
{
}
>>620 サンクス
もう一つだけお願い
typedefした場合の初期化はこれでOK?
class Foo {
typedef vector<string> vec;
public:
Foo();
~Foo();
};
Foo::Foo()
{
vec(5);
}
STL関係ねーな
C++ですらないもんな
まぁ、初心者スレに逝っとけと。
日本語(UTF8)(ひらがな、感じ含む)文字列のソート処理をSTLのコンテナと アルゴリズムを使って可能でしょうか?可能な場合どうすれば良いでしょうか?
>>626 できそう。ソート順が望むものになるかどうかわかんないけど。
っていうか、自分で試してから相談しろよ。できそうにないと思うならその理由付きでな。
結果はともかくとりあえずソートするだけなら 通常のASCIIと同じやり方で問題なし
>>621 その場合のFoo::vecは型だ。
インスタンスに初期化を施すという常識をぶち破って型に対して初期化なんてもう訳が分からない。
それで何をしようとしている?vec(5)は単に、使えないvector<string>のインスタンスを作っているに過ぎない。
もし有用な閃きでもしたんなら、びょーんすっぽすっぽに直に談判してこい。
〆⌒ヽ (#‘д‘) < だ、だれがハゲやねん! ∪ l| || @ノハ@ =3 ペシッ!!
631 :
デフォルトの名無しさん :2007/11/27(火) 21:42:51
const なメンバを持つようなクラスは operator = をうまく定義できませんよね? (コピーコンストラクタは定義できますが) ということはコンテナには入れることができないということでしょうか?
それは自分の作ったクラスに関して、自分で意味付けしていく領域。
operator=でconstメンバを無視すればいい話じゃん。
うまく定義できないってなんだ? 定義すればいいだろ
shared_ptrなんかをコンテナの要素にすればいい(という場合もある)。
質問なんですが、 wstringにはコピーコンストラクタは実装されて いるのでしょうか? 関数にパラメータでwstringのインスタンスを 渡したら、実行時エラーになってしまいます。
>>636 wstring はコピーコンストラクタでコピーを生成できる。
問題が再現する最小のソース作ってみて。
できたら、使ってるコンパイラも添えて貼ってみてほしい。
>>637 コンパイラ :Visual Studio 2005 Express Edition
#include <iostream>
#include <string>
using namespace std;
wstring display(wstring path){
wstring work = path;
int i;
//パスの最後の\の位置を調べる
i = work.find_last_of(L'\\');
//それより後の部分を取り出す。
work = work.substr(i + 1, work.size());
return work;
}
int main(){
wchar_t *org = L"origi\\nal";
wstring *worg = new wstring [1];
worg[0] = org;
wcout << display(worg[0]) << endl;
return 0;
}
よろしくお願いします(^人^)
>>638 VS2005EE で試してみたけど、 "nal" って表示されて終わった。エラーは出ない。
エラーメッセージは?
> work.substr(i + 1, work.size()); work.size() にしてるのは問題ないんだっけ? というか最後まで取り出すなら work.substr(i+1) でいいよね。
wstring display(wstring &path) じゃなくて wstring display(wstring path) なんだよね っつーことは wstring work = path; より前に既に関数呼び出しの時点で 引数渡しのためにコピーコンストラクタが(ry
i = work.find_last_of(L'\\'); i = work.find_last_of(L"\\");
VC2005EE で wchar_t *org = L"origi\\n表al"; で試したら n しか出力されませんでした 本当にありがとうございました
wcout.imbue(std::locale("japanese")); くらいしろと
645 :
デフォルトの名無しさん :2007/11/28(水) 09:23:59
>>644 locale に渡せる言語の一覧ってどこ?
647 :
デフォルトの名無しさん :2007/11/28(水) 12:42:48
>>646 ふぅむ、それは処理系というかライブラリ依存なのか。
もっと、なんつーか、ISO とか IANA で決まってるのかと思ってた。
そこがC/C++らしさだけど、使う気を失せさせるのは確か。 主要なライブラリベンダ同士でC/C++標準とは別に取り決めでもしてくれればいいのにと思う。 ちなみに""と"C"だけはどの処理系でも使えると決まっている。
649 :
デフォルトの名無しさん :2007/11/28(水) 18:59:29
それが POSIX なんでは?
そうなんだよ。だけど、Win32サブシステムの 普通のWindowsアプリケーションに適用できないのが痛い。
POSIX には "" と "C" に加えて "POSIX" ロケールがあるが、他は実装依存
Linuxのってことはlibstdc++だろうけど、以前コードを見たときには ろくすっぽ実装されてなかったような……
商用UNIXならまともなんだけどね。
654 :
デフォルトの名無しさん :2007/11/29(木) 19:17:53
reverse_iterator とか const_reverse_iterator を使うと なぜか Visual Studio では IntelliSense がしぬ.
655 :
654 :2007/11/29(木) 19:55:22
もっと限定された状況だった. std::list<T>::reverse_iterator std::list<T>::const_reverse_iterator これを使うと以降 IntelliSense がしぬ.
IntelliSenseを捨ててからC++は始まる
Boostバリバリ使おうと思ったらIntelliSenseなんて既に死んでるぜ。
C++という言語自体、コンパイラ以外(場合によってはコンパイラすら) による解釈を激しく拒むタイプの文法構造になってるというのは有名な話だな
は?
661 :
654 :2007/11/30(金) 07:04:50
>>658 英語版 Visual C++ 2008 Express Edition では生きた.
662 :
654 :2007/11/30(金) 07:05:22
>>657 しかしそろそろ c++0x の auto が無いと死にそうな予感.
max_elementアルゴリズムって、構造体型の要素を持つvectorにも使えますか? typedef struct data { string yymmdd; int code; double openprice; } data; vector<stockdata> workcontainer; ...データを入れたとして... この様な構造体の要素を持つベクトルのopenpriceの最大値を求めるのに double max = max_element( workcontainer.begin()->openprice, workcontainer.end()->openprice ); としたら error C2100: 間接指定演算子 (*) の使い方が正しくありません。 となるんですが、何処が間違ってますか?
>>663 呼出しが間違い。
max_elementにはiteratorを渡すこと。
>>663 このスレでは割とよくでる質問らしいけど、
比較用の関数オブジェクトを用意してやるとうまくいくみたい
STLの関数等にどんな型のオブジェクトを渡してやればいいかは
ttp://www.sgi.com/tech/stl/を参考にすれば概ね問題無いようだ #include <algorithm>
#include <string>
#include <vector>
#include <cassert>
struct data {
data(double d) : openprice(d) {}
std::string yymmdd;
int code;
double openprice;
};
bool compare(data const& lhs, data const& rhs) {
return lhs.openprice < rhs.openprice;
}
int main() {
std::vector<data> v;
v.push_back( data(0.01) );
v.push_back( data(0.1) );
v.push_back( data(0.2) );
double max = std::max_element(v.begin(), v.end(), &::compare)->openprice;
assert( max == 0.2 );
}
>>665 先生デキマシタ+。:.゚(嬉´Д`嬉)゚.:。+゚ わぁい♪
>>このスレでは割とよくでる質問らしいけど、
そうなんですか、漏れも一般的な2ちゃんねらーということですねww
ところで、一点質問お願いします
初期化子で
data(double d) : openprice(d) {}
このように書かいてもらいましたが
自分は最初下記のように書いてたのですが、これでもOK?
openpriceはdouble型即ち、組込み型なのでいいと思うのですが、いかがなものでしょうか?
struct data {
std::string yymmdd;
int code;
double openprice;
stockdata() : yymmdd(""), code( 0 ), openprice( 0.0 ){}
};
上の例では生成と同時にdata::openpriceに値を設定したかったから、それを実現するコンストラクタを用意しただけ どんなコンストラクタを用意するべきかは「どんな初期化をしたいか」によるから、 「組み込み型はデフォルトで0って初期化もありでしょう」ぐらいしか言えない
>>667 先生( ̄〜 ̄;)ウーン・・・ 深いデツネ
>>上の例では生成と同時にdata::openpriceに値を設定したかったから
ってことは、
data() : yymmdd(""), code( 0 ), openprice( 0.0 ){}
これでは、生成と初期化が同時に出来ないということなんですね(自分では出来てるつもりだった^^;)
メイヤー先生の本をもう一回読み直して出直します。
ありがd
669 :
デフォルトの名無しさん :2007/12/01(土) 15:11:59
std::multimap に対しては std::sort を適用できないですよね? そもそも map/multimap に対してソートって意味ないような気もしますが, map/multimap 同士に std::includes を適用したいことはあると思うのです. しかし std::includes はソート済みのコンテナ同士に対してしか 適用できません. std::multimap<int,int> multimap1; multimap1.insert(std::pair<int,int>(1,2)); multimap1.insert(std::pair<int,int>(1,3)); multimap1.insert(std::pair<int,int>(2,5)); std::multimap<int,int> multimap2; multimap2.insert(std::pair<int,int>(2,5)); multimap2.insert(std::pair<int,int>(1,2)); multimap2.insert(std::pair<int,int>(1,3)); のような二つの multimap に対して std::includes を適用した結果は true になりますが,たとえば std::multimap<int,int> multimap2; multimap2.insert(std::pair<int,int>(2,5)); multimap2.insert(std::pair<int,int>(1,3));←ここがちがう multimap2.insert(std::pair<int,int>(1,2));←ここがちがう とすると false になります.Visual C++ 2008 でデバッグバージョンで ビルドすると STL の内部のアサーションで「ソートされてない」 として実行が中断されます.かといって std::sort(multimap2.begin(), multimap2.end()); はコンパイルできません. multimap 同士で STL の集合演算を行うことはできないのでしょうか?
>669 同じキーに対する要素間でのソート基準が規定されてないから。 multimap 以外は使えるんじゃない?
そういう風にしたいのだったら、キーと値の両方がソートされた状態になるように、 multimapではなくstd::set<std::pair<int, int> >にでもするほうがいいと思う。
JavaやC#を先にやったので、オブジェクトをコピー渡しして格納が基本の STLのvectorやmapが凄く効率悪いような気がしてならないんですが、 そのへん、どう考えたらいいんでしょう? 一応自分なりに考えて見たんですが↓、正解有ります? (1) C++は全般的にJavaやC#より速いので、気にするのは無益。 (2) 熟練プログラマはオブジェクトへのポインタを格納するのが普通なので速い。 (3) 熟練プログラマはshared_ptrを使うのが普通なのでC#と同等。
たとえば、物凄くサイズの大きい型を、物凄い頻度でソートしまくる必要がある場合、 vector<T>じゃなくてvector<T*>を選ぶことはある。 でも、Tがポインタと同サイズだったら、コピーのコストは変わらず、読む速度はむしろ速いわけで、 STLはこっち、つまり「最速を叩き出す道を仕様によって閉ざさない」ことのほうを重視してる。 あと、mapはコピー渡しのコストとはあまり関係無いはず。 大抵、mapが持っているのは struct node { pair<key_type, mapped_type> value; node* prev; node* next; }; みたいなノードで、挿入や削除のたびにポインタを付け替えてるだけだから。
>>639 ---------------------------
wstring.exe - アプリケーション エラー
---------------------------
"0x7c950de3" の命令が "0xffffffff" のメモリを参照しました。メモリが "read" になることはできませんでした。
プログラムを終了するには [OK] をクリックしてください
---------------------------
OK
---------------------------
実行するとこのようなダイアログが出ます。。
>>672 C# で値・参照型 ( struct/class ) を検討する場合を考えたら良いと思う。
データがポインタサイズ以下である事が多いなら、
>>673 の書いているとおり、
コピーの方が速く、逆ならば参照型 ( Copy On Write )で設計した方が良い。
(2)、(3) の方法だと、データを使用する側でコストを意識する必要があるが、
データ型が予め適切な型 ( 値・参照 ) として設計されていれば、使用側は単純
なコピーだけ考えれば良いし、後に値・参照を切り替えたくなった時でも、
データ型の内部実装を変更するだけなので、メンテナンスコストも低くなる。
>>674 >>638 のコードコンパイルに成功して、実行できたぞ?
"0x7c950de3" の命令が "0xffffffff" のメモリを参照しました。メモリが "read" になることはできませんでした。
はいわゆる、メモリ保護違反のことだ
これ豆知識な
>673 >675 参考になります。 ちなみに、C#で値型・参照型の使い分けは、経験的に16byteぐらいが目安とか MSの中の人がMSDNかどこかで書いてました。 C++でもポインタサイズ(+α)の目安が有りそうですね。
>>677 一応boostにptr_vectorってのがあるぞ。
std::vectorをそのまま置き換えるだけじゃうまくいかない部分もあるらしいけど。
>>676 IDEからコンパイルしてますか?
コマンドラインからコンパイルしてますか?
私はIDEからコンパイルしているんで、同じようにIDEから
コンパイルしているなら、私のIDEの設定がどこかおかしいようですね・・
IDEの設定なんか項目数が多すぎてどうやって比較したらいいんだろ・・
>>IDEからコンパイルしてますか? うん >>IDEの設定なんか項目数が多すぎてどうやって比較したらいいんだろ・・ 文字セット、プリコンパイルの設定くらいかな、自宅のPCの場合 仕事だとライブラリィ関係のパスやMFCだとDLLリンクかスタティックリンクあたりも 気にするが?
682 :
679 :2007/12/02(日) 15:56:50
デバッガでどこで落ちてるか調べた方が早い
685 :
デフォルトの名無しさん :2007/12/02(日) 16:28:38
686 :
679 :2007/12/02(日) 19:36:25
>>683 デバッガだと落ちないんです。
>>684 ありがとうございます!早速比較してみましたが、
特にこの問題にかかわるような差異は見つけられませんでした・・
VS自体を再インストールしてSP1を当ててみましたが、
結果は同じでした。
ちょっともう手に負えないので残念ですが諦めようと思います。
ありがとうございました;;
687 :
デフォルトの名無しさん :2007/12/04(火) 12:32:35
std::logical_and のように、 bitwise で論理積をとってくれるファンクタは用意されていませんか? 自分で用意する必要があるでしょうか? 用意すること自体は簡単なんですが、 標準的なファンクタがあるならそちらを使ったほうがいいかと思って。 boost::mpl も探してみたんですが、 bitand.hpp はみつかったものの どうも自分がいとしているものとは違うようです。
688 :
デフォルトの名無しさん :2007/12/04(火) 16:52:01
あるファンクタ f1 の結果が新のときのみ 別のファンクタ f2 を適用したいと思っています。 これを実現する合成ファンクタを生成する簡単な方法があるでしょうか?
689 :
688 :2007/12/04(火) 19:01:24
boost wiki にある for_each_if を使うことにしました。 これが C++0x に入ってくれたりするんだろうか。 そもそも copy_if が標準にないし。
mapは数字、大文字の英数、小文字の英数って順番でソートされていますよね? これを、大文字と小文字を区別しない辞書順に変えたいのですが どうすればいいでしょうか?
大文字小文字を区別しない比較関数オブジェクトを作って、 mapのテンプレート引数3番目にデフォルトのless<T>の代わりに入れる
たびたび失礼します。 そのようにした場合、大文字と小文字を区別しないと、例えばTESTとtestがあった場合にはtestが2つみたいになってしまうんですか? そうならないようにしたいんです。 説明下手ですいません
testとTESTを区別したいってことか?それなら A < a < B < b < C < c ... みたいな順序で辞書順にすれば良い。
すいません、調べてみたんですがどうやってやったらいいか分かりません 教えていただけませんか?
>>694 何を調べて結局何がわからなかったのかはっきりさせようよ。
・関数オブジェクトの作り方
・A < a < B < b < C < c ... の比較の仕方
すいません。 関数オブジェクトの作り方から調べたんですがよく分かりませんでした。 比較の仕方も具体的にどうやればいいのか教えていただけると助かります。
>>696 operator() を持つクラスを作るだけだよ。
struct comp
{
bool operator()(const string& s0, const string& s1)const {
// 比較
// s0 が s1 より小さい(先にくる)ならtrue, そうでなければfalseを返す
}
};
map<string, int, comp> hoge;
実際の比較処理はSTLの範囲外だし文字列処理の初歩なのでがんばってくれ
>>692 >0そのようにした場合、大文字と小文字を区別しないと、例えばTESTとtestが
>あった場合にはtestが2つみたいになってしまうんですか?
ならないから、
>>693 >>695 は無視して安心してください。
class comp : public binary_function<string,string,bool>{ public: bool operator()(const string& s1,const string& s2)const{ for(int i=0;i!=s1.length();i++) toupper(s1[i]); for(int i=0;i!=s2.length();i++) toupper(s2[i]); if(s1<s2) return true; else return false; } }; いろいろ探しながらやってみたらこうなったんですけど 大文字の辞書順が先に出て、次に小文字の辞書順が出てきたままでした。 なにがいけないんでしょうか
>>699 s1="abc"、s2="ABC" を入れたときの動作と
s1="ABC"、s2="abc" を入れたときの動作を考えてみろよ
それだとどっちも false が返ってくるじゃん
>>696 調べたって、どういう風に調べたの?
「関数オブジェクト」で検索したら、定義と作り方が丁寧に書いてあるページばっか出てきたけど。
もしこれらを見てもわからなかったというのなら、つまりそれより詳細でわかりやすい説明を
このスレに書き込めって要求してることになるが、それは無茶というものだよ。
class comp : public binary_function<string,string,bool>{ public: bool operator()(const string& s1,const string& s2)const{ for(int i=0;i!=s1.length()||i!=s2.length();i++){ if(toupper(s1[i])<toupper(s2[i])) return true; else if(toupper(s1[i])>toupper(s2[i])) return false; } if(s1<s2) return true; else return false; } }; これでどうでしょうか?
>>699 toupperの使い方がまるで違う
for(int i=0;i<s1.length() && i<s2.length();i++)
{
unsigned char c,d;
c=s1[i];
d=s2[i];
if(toupper(c)!=toupper(d)) return toupper(c)<toupper(d);
else if(c!=d) return c<d;
}
return s1.length() < s2.length();
試してないから合ってるから知らん
stricmp は使わないの?
lexicographical_compare使おうぜ。 struct mixcomp_char : public std::binary_function<char, char, bool> { bool operator()(char x, char y) const { char lx = std::tolower(x); char ly = std::tolower(y); if(lx < ly) return true; if(lx > ly) return false; return x < y; } }; struct mixcomp : public std::binary_function<std::string, std::string, bool> { bool operator()(const std::string &x, const std::string &y) { return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), mixcomp_char()); } };
706 :
デフォルトの名無しさん :2007/12/07(金) 00:27:54
>>706 で、どういう風に調べたの?
ここの住人を「ああ、こいつはちゃんと調べた上で質問してるんだな」と納得させられる調べ方は
まるでしてなかってことかな?
708 :
デフォルトの名無しさん :2007/12/07(金) 22:13:51
最近はなんの保障もないweb上の情報など使わない 調べるだけ時間の無駄 本屋行ってみれば情報量の高い有益な情報が手に入る。 (なかには使い物にならないものもあるが)
本屋に行く時間と金がもったいない貧乏人はweb
本屋に入ったって結局本を選別する技術が必要。 ネットより比率がマシってだけで大して変わらん。
>710 そういうセリフは英語を使えるようになってから言え。
#include <algorithm> #include <iostream> #include <vector> struct data { data(int d) : num(d) {} data(double db) : openprice(db){} int num; double openprice; }; inline double comp(const data& lhs, const data& rhs) { return lhs.openprice < rhs.openprice; } int main() { std::vector<data> v; v.push_back( data(1) ); v.push_back( data(0.1) ); v.push_back( data(2) ); v.push_back( data(0.2) ); v.push_back( data(3) ); v.push_back( data(0.3) ); double MAXOF = max_element(v.begin(), v.end(), &::comp)->openprice; std::cout << MAXOF << std::endl; return 0; } 上記のコードではcomp比較関数でopenpriceの最大値を取得しているのですが、 openpriceの大小を比較して、戻り値としてその値と同じ構造体エレメントに属する numの値を取得する場合の比較関数の書き方を教えてもらえないでしょうか。 (例えばこのコードの場合、3という値を望みます)
>>714 比較関数はそのままで、
max_element(v.begin(), v.end(), &::comp)->openprice
を
max_element(v.begin(), v.end(), &::comp)->num
にすれば良い。
あと、そのコードは初期化のやり方がおかしい。
v.push_back( data(1) );
v.push_back( data(0.1) );
こうすると、
・num=1, openprice=不定
・num=不定, openprice=0.1
の二つのdataがvに入るが、意図としては
num=1, openprice=0.1
という一つのdataを入れたいんだよな?
716 :
デフォルトの名無しさん :2007/12/08(土) 15:54:28
std::for_each の第三引数はなぜ値渡しなのでしょうか? 参照渡しのほうが内部状態を持ち続けたいときなどに 便利だと思うのでが.効率の面からですか? もちろんファンクタが持つべき内部状態をカプセル化して boost::shared_ptr などで持たせればいいのですが, 不思議に思ったので.
>>716 単純に非 const 参照にすると、その場で生成したファンクタを渡せない。
const 参照にすると operator () に const が付いてないと使えない。
こんなとこじゃないの?
718 :
714 :2007/12/08(土) 16:23:27
>>715 さん
どうもありがとうです、
>num=1, openprice=0.1
>という一つのdataを入れたいんだよな?
そうなんですが、これでいいのかな?
#include <algorithm>
#include <iostream>
#include <vector>
struct data {
int num;
double openprice;
data():num(0), openprice(0.0){}
};
inline double comp(const data& lhs, const data& rhs) {
return lhs.openprice < rhs.openprice;
}
int main() {
std::vector<data> v(3);
v[0].num = 1;
v[0].openprice = 0.1;
v[1].num = 2;
v[1].openprice = 0.2;
v[2].num = 3;
v[2].openprice = 0.3;
double MAXOF = max_element(v.begin(), v.end(), &::comp)->num;
std::cout << MAXOF << std::endl;
return 0;
}
でもこれだと、push_back()関数やイテレータを定義して、insert()関数での代入が出来
なくなるのかな?構造体が絡むと混乱してしまいます・
719 :
714 :2007/12/08(土) 16:25:32
失礼しました ×double MAXOF = max_element(v.begin(), v.end(), &::comp)->num; ○int MAXNUM = max_element(v.begin(), v.end(), &::comp)->num; こうです
>>718 引数を二つとるコンストラクタを作れば良い。
struct data {
data(int n, double db) : num(n), openprice(db){}
int num;
double openprice;
};
...
v.push_back( data(1, 0.1) );
二引数をとるコンストラクタを定義しないのかね
>>718 本題と関係ないが、特に理由がないならcompはboolを返すべき
723 :
714 :2007/12/08(土) 16:54:31
>>713 欧米のサイトは十分実用に耐えうるってこと?
一次ソースは英語がほとんどだから、翻訳されたものよりは信頼性はあるんじゃね。
本は良書だけピンポイントで買うもんじゃないか 普段の情報集めはwebで
え?本てとりあえず目に付いたものを、 予算消化とクレカポイントとアマゾンポイント狙いで 立替払いで買うもんじゃないのか。
俺はじっくり腰を据えるタイプだから、良書はなるべく買って読んでる 今はメイヤーズ先生のEffective STLを読んでる処だよ、先にSTL標準講座を買ったが おさらい程度でざっくりと読んで、基本的なことで分からないことがあった場合、 付箋を貼りながら開いているな。
画面を見つづけるより本を見るほうが疲れないし好きなんだけど、 本を見ながらコーディングするときって、どういう配置にすれば良いかいつも迷う。 今はキーボードの手前に本を置いて、キーボードを打つのと本を抑えるのを兼ねてるんだけど違和感ありすぎる。
>>729 つ ほんたった
あんまり使ってないけど
webでもいい情報はあると思うけど… jisc.orgのJISX3014とかMSDNとか
>>730 お、こんなのあるんだねー。
安いし試しに買ってみようかな。
vector型の空コンテナに対してerase()関数を実行すると、 当然Assertionで落ちますけどこの例外がcatchできる、関数を教えてもらえないでしょうか?
734 :
デフォルトの名無しさん :2007/12/09(日) 09:36:54
std::out_of_range じゃないの? とか思い付きで言ってみる. そんなことより,Java の Generic ってテンプレートと 同じくらい強力なものなの?教えてママ.
> 23.2.4.4 > Throws: Nothing unless an exception is thrown by the copy constructor or assignment operator of T. 要素のコピーコンストラクタか代入演算子が例外投げなければ投げない ってあるから、std::out_of_rangeは投げない。 存在しない要素のeraseは未定義動作。
736 :
733 :2007/12/09(日) 12:00:28
>>735 サンクス
ていうことは、空のvectorコンテナをerase()しないようにしないと、いけない訳で
要素が空か否か、判定するベターな方法は、どうしたらいいのかなぁ?
738 :
733 :2007/12/09(日) 12:53:16
empty()は至極普通に、最初に試したんだけど、上手くいったり、いかなかったり(Assertion落ち) なんだよね、今find()関数の比較演算子(==)をオーバーライドして、専用のクラス作って 何となく上手くいきそうな悪寒です、なんかさerase()やempty()で空のvectorコンテナ操作するときって 注意が必要だね。
emptyで落ちるのはおかしい。 それ以前に内容が破壊されてるんじゃないか?
740 :
733 :2007/12/09(日) 13:02:57
>>739 そうかもね、STLでのデバッグはなちょいと読み辛いから、しんどいな・・・・
> なんかさerase()やempty()で空のvectorコンテナ操作するときって注意が必要だね。 erase()はともかくempty()は注意する必要などないよな
742 :
デフォルトの名無しさん :2007/12/09(日) 13:18:47
そうだな. 世の中には二つのコンテナしかない. empty() か empty() でないか,だ.
743 :
733 :2007/12/09(日) 13:31:39
あ!そうか std::vector<data> v; std::vector<data>::iterator iter; iter = v.begin(); iter += 2; if(!v.empty()) ・・・・・・ こんな感じで、コンテナの特定Elementの有無を判定している、つもりだったんだけど やり方が不味かったのかな? find()関数のいオーバーロードでロジックは完成したんだけど、empty()関数使って コンテナがぶっ飛ぶってのが凄く薄気味悪い!?((((;゜Д゜))).
>>743 そもそも何のコードを書いてて落ちるだの飛ぶだの言ってるの?
> iter = v.begin();
> iter += 2;
> if(!v.empty())
こことか何をしたいのか意味がわからないし、
> コンテナの特定Elementの有無を判定している
という表現もよくわからない
745 :
デフォルトの名無しさん :2007/12/09(日) 13:38:52
iter += 2 の前に何とかしてほしい気もするが, empty() で落ちるってのはなんかおかしいなぁ.
746 :
733 :2007/12/09(日) 13:41:45
iter = v.begin() + 2; こいういう事?
というか、iterをどうこうする前に、emptyチェックかけとけよ
順番が違うよな。 emptyではないことを確認してから、beginとかを呼ぶんだよ。
749 :
745 :2007/12/09(日) 13:58:41
750 :
733 :2007/12/09(日) 13:59:51
ざっくり言えば、構造体を要素にもつvector型のコンテナがあって、その構造体には 他のvectorや、自身(構造体)が何番目のキーが入力されて出来たデータとかの、 情報が入っています、まぁ管理テーブルのようなものと思った欲しい なので、制約があって 1のキーを押下→v0番目に格納 2のキーを押下→v1番目に格納 3のキーを押下→v2番目に格納 4のキーを押下→v3番目に格納 5のキーを押下→v4番目に格納 6のキーを押下→v0番目に格納したベクトルを削除 7のキーを押下→v1番目に格納したベクトルを削除 8のキーを押下→v2番目に格納したベクトルを削除 9のキーを押下→v3番目に格納したベクトルを削除 10のキーを押下→v4番目に格納したベクトルを削除 こういう実装がしたかったわけよ、そこで最初vector を固定長にしようとしたら、複雑になることに気付き、構造体に、何番目のキー入力で 出来たかって情報を付加し、削除する場合そのキーを検索して削除するってロジックに 落ち着いたって感じなんだよね、そこでキー入力後、管理テーブルベクターで 同じキー入力があった場合、はじくためにempty()を使いたかったんだけど、 上手くいかなかったんだよね
iter += 2 でも begin() + 2 でも、その時点で既にコンテナ末尾(end())を超えてるんでやばいんじゃねーの、と言われてるんだよ。 >748 先に確認しとけ、とは思うけど、empty() でも begin() は呼んでも問題ないっしょ?
>>751 ああ、まぁ、確かに。
end()の戻り値と同じものが呼ばれるだけで、扱いが正しければ害は無いよな。
>750 さっぱり分からない。多分コード見せてもらった方が…、でもやっぱり分からん気もする。 とりあえず、v0 〜 v4 はそれぞれ vector なのか?、vector の特定の位置なのか? そもそも vector である必要があるんか?なんとなく、map 使えば良さそうな気がするんだが。
>>750 そういうのは関係無いと思う。
>>743 のコードが問題なのは、「中身をいじり始めてから、中身があるかどうかを確認している」ところ。
それって、飛び降りてからパラシュートを付けてるかどうか確認するようなものだよ。
>>750 たぶんvectorの使い方をわかってなさそうなので、もっとシンプルな構造でテストすべきだと思うよ。
いつものことだが もう全部貼れよw
もし空だったらiter += 2この時点で鼻から悪魔
どうせ iter += 2 の中で assert 失敗してるんだろ。
>>743 凄く薄気味悪い って、おまえが凄く薄気味悪いコード書いてるからだよ。map使え
同じ、データ同士をマージしたらどうなるの やっぱ未定義動作?
>>760 何でやねん
mergeは重複要素を除外しない
set_unionは重複要素を除外する
それだけの違い
vector <MyClass> array; とした時に、array 中の指定した文字列と同じ文字列を持つ要素があるかどうかを調べる 関数を書きたいのですが、MyClass c ; とやって c との比較なら array.find()で出来るのですが その中の一メンバー変数の比較をしなきゃならないんですが、このような場合はどうするのが 良いでしょうか?
array 中の → array 中に
763です。 Thx!
find_if
768 :
デフォルトの名無しさん :2007/12/16(日) 16:56:46
std::stackって、なんでstd::dequeのアダプタという形で実装されているんでしょうか?std::queueと違って配列末尾でしか要素の追加削除がされないのだから、vectorで実装してもよさそうですが。 stack作成時にテンプレートのパラメタでvectorを使うように指定できるのは知ってます。デフォルトがdequeになっている理由がわからないです。
>>768 vector は再確保が発生するときのコストが大きい。要素数の上限が分かっていれば
reserve() した vector を使うのがいいんだろうけど、どっちかというと要素数に対する
前提が無くても極端な特徴の無い deque をデフォルトにしとくのは妥当なところだと思う。
知ってのとおり vector も選べるしね。
770 :
デフォルトの名無しさん :2007/12/16(日) 17:20:46
>>769 回答ありがとう。
典型的なdequeの、内部で抱えているバッファって単純なchar配列1つではない?
1つのchar[]をリングバッファとして使っているだけかと思っていました。
771 :
770 :2007/12/16(日) 17:29:51
char[]はT[]の誤記です。
>>770 ひとつの配列だと結局再確保が発生するときに O(n) になるから、計算量の要件が
満たせないでしょ。
STLport の実装見たら、固定サイズの配列を T* の配列で持ってた。
773 :
デフォルトの名無しさん :2007/12/16(日) 18:23:36
>>772 えーと、メンバとして T** m_nodes; を持っていて、コンストラクタで
m_nodes = new T*[3];
m_nodes[0] = NULL;
m_nodes[1] = new T[N];
m_nodes[2] = NULL;
とかしておいて、push_front(x)されたらm_nodes[0]にもnew T[N]してやってそこに値xを覚えるとかでしょうか?
>>773 特定の実装の詳細知りたければソース見れば? STLport だって言ってるんだし。
>>772 vectorとdequeは末尾への要素追加に対する計算量の要求は同じで、vectorは配列で実装されているわけだが・・・
それについてはどうなの?
>>775 vector の push_back は Sequence で定められる償却定数時間なのに対して
deque の push_back および push_front は定数時間とされている。
23.2.1 Class template deque の p1 より
> A deque is a kind of sequence that, like a vector (23.2.4), supports random access iterators. In addition,
> it supports constant time insert and erase operations at the beginning or the end; insert and erase in the middle
> take linear time.
>775 deque: Inserting a single element either at the beginning or end of a deque always takes constant time and causes a single call to the copy constructor of T. vector の方はあくまで amortized な。
>>776-777 deque先頭末尾はamortizedではないのか。それ、厳密にやろうとするとlistにしないと無理だったりしない?
STLPortの方法が常にconstantとは思えないのだが。
listでいいわけがない。。。。ランダムアクセスできないとだめだったorz
俺もGNU libstdc++のソース見たけど、T *の配列を再確保するときに線形時間掛かるように見える
>>781 >23.1/2 says, "All of the complexity requirements in this clause are stated
>solely in terms of the number of operations on the contained objects."
これは知らなかった。ポインタ操作は定数回じゃなくてもいいのか
newによるメモリ確保の計算時間って、規格ではどうしろっていってんの?
>>784 コンテナの操作の計算量に関する要求は標準の23.1にあるわけだが、
ここで要求されている計算量は、操作に掛かる時間そのものについてじゃなくて、
「コンテナ内のオブジェクトを操作する回数」についてのものだと規定されてる
たとえばvectorに対するpush_backなら、要素のコピーコンストラクタを償却O(1)回呼ぶってことだ
で、libstdc++(たぶんstlportも)のdequeの実装だと、最悪O(n)回のポインタ代入が発生するけど、
要素のコピーコンストラクタは常に1回しか呼ばれないので、規格の要求するO(1)は満たしてることになる
>>785 list に operator [] つけてもおk・・・になっちゃうよねぇ。
標準では vector<vector<int> > のコピーコンストラクタは O(N) ですよと言っているだけ O(N×M) じゃないですよと そのほかは常識的に考えようね
日本語でおk
委員会の意図がなんであろうと書かれていることが全てだろ
794 :
デフォルトの名無しさん :2007/12/16(日) 23:49:03
std::listのsize()って線形時間かかるの実装が多いの? サイズくらい4バイト程度なんだから変数で覚えとけとおもうんだけど。
>>794 変数で覚えてても splice() されたら変わってしまう。
サイズを覚えとくとspliceが定数時間でできなくなるから、トレードオフだな
>>793 やっぱりある程度は常識で処理しないとだめなんじゃないかな
23.1/2 を常識的に読むと list<T>::operator[] が O(1) にはならない
>795-796 どうもありがとう
Effective STLには確か、どっちの実装もありうるから覚悟しとけ、と書いてあったな。 環境依存でよいなら実測汁。
>>797 いや、常識的に考えると list<T>::operator[] は O(n) だけど、 23.1/2 を
(常識的にでもなんでも)読んでしまえば O(1) と言えると考えざるをえないでしょ。
で、何かおかしいって話だよ。漁ったらこんなん出てきた。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1996/N0937R1.asc あの記述が追加されたのは、要素型によっては実時間が定数時間にはならないという
問題を解決するため。つまり規格中の deque の要件がこの追記より前に定められていた
場合、単純に規格化の際に amortized を書き漏らした可能性があると。
>782 で挙げられた SGI のドキュメントに amortized が付いてることから考えても。
>>797 俺にはそうは読めない
もしかしてそういう意図だったのかな、と想像することはできるけど
というか自分の主観を常識として語るのやめろよ
さぁ、きな臭くなってまいりました
wktk
常識なんて言葉使ってるやつはたいがいハッタリ君
red-black treeのiteratorってどうやって実装するんだろ
おい
>>799 俺も、かの有名なメイヤーズ先生が書いた、凄く薄っぺらの「Effective STL」を読んでいるが、、一向に脳内で咀嚼できず、前に進めない、
お前はどれ位で、この本を理解するのに、なん時間位かかった?
現在策定中の次期標準仕様でコンテナの計算量についての記述は修正されてるの? 少なくとも 23.1/2 は N2461 でもそのままだけど
>>807 修正というからには、まずどこが間違っているのか挙げてもらおうか。
ここでいいのか迷いましたがこちらで質問させていただきます。 vectorの特定の要素へのイテレーターを返してほしいばあい、どうすればいいのでしょうか。 vector<double> vec; vec.resize(100); vector<double>::iterator it; hogehoge(); double d = vec[12]; //double d = *it; //この行で、一行上の記述と同じことをさせたい この場合はどうすればいいのでしょうか? どうせポインタだから、って参照をそのまま代入したらエラーになったし、 勇気を出してキャストしてみてもエラーになりました。 よろしくお願いいたします。
810 :
デフォルトの名無しさん :2007/12/18(火) 10:16:08
it = vec.begin() + 12; とか、 it = vec.begin(); std::advance(it,12);とか。
ありがとうございます。 大変助かりました。
test
たぶん過去ログに無かった・・・と思うんだけど class Test1 {public: int base; Test1() { base = 0; } void Add(int n) { base += n; } }; void hoge() { vector<int> v; Test1 test; v.push_back(1); v.push_back(2); v.push_back(3); for_each(v.begin(), v.end(), test.Add); // ここでエラー printf("%d", test.base); } これ解決するにはやっぱりイテレータでループ回すしかないんでしょうか。 上記のTest1クラスはあくまで例なので実際には別のクラスですけど。
>>813 Boostにはそういうことをするためのbindというライブラリがある
標準にはない
815 :
814 :2007/12/18(火) 16:10:33
俺は何をねぼけてるんだ std::mem_funがあるじゃないか
>>813 結果はtestに入らないよね?
Test1 result = for_each(〜略
あ、ごめん、勘違い。
818 :
813 :2007/12/18(火) 16:19:23
mem_funあたりは真っ先に試してみてるんだけど、 for_each(v.begin(), v.end(), test.Add); ↓ for_each(v.begin(), v.end(), mem_fun(&Test1::Add)(&test)); これでもやっぱりだめなんですよね。
for_each(v.begin(), v.end(), std::bind1st(std::mem_fun(&Test1::Add), &test)); これでできた
820 :
813 :2007/12/18(火) 16:33:54
>>819 ありがとう。ちなみにboost使ってもいいんだけど、それならもっと簡略化できますかね?
for_each(v.begin(), v.end(), boost::bind(&Test1::Add, test, _1));
822 :
813 :2007/12/18(火) 16:41:10
それでいけそうです。どうもありがとう。
testはboost::ref(test)にしないとだめじゃねーか?
むしろポインタ渡しじゃね? for_each(v.begin(), v.end(), boost::bind(&Test1::Add, &test, _1));
C++初心者だけど Effective C++買ってみた。
で?
いま俺の横で気持ちよさそうに寝てる
あべさんが?
>>824 で bind の第二引数を &test にしたら
自動的に参照渡し,test にしたら自動的に
値渡しになるの?
boost::bind すげぇ〜
んで,boost::lambda とどちら使えばいいんだ?
教えて!
830 :
デフォルトの名無しさん :2007/12/19(水) 21:52:36
>>829 boost::lambda::bind
class Test { private: typedef boost::function<int, int> Functor; Functor calc; int num; public: Test(const string& str) : num(1) { map<string, Functor> funcs; funcs["plus"] = boost::bind(&Test::plus, this, _1); funcs["multiply"] = boost::bind(&Test::multiply, this, _1); this->calc = funcs[str]; } int operator()(int n) { return this->calc(n); } private: int plus(int n) { return this->num + n; } int multiply(int n) { return this->num * n; } }; こういうのって有り?
funcsをコンストラクタで使い捨てにするんだったら、抵抗感あるな。 俺なら普通にifで切り分けていく。 あるいはそのmapを静的に持つ。
LL言語なら普通にやるパターンだが。 パフォーマンスで問題が表面化しなければそれでいいんじゃないかね。 意図通りに動くのであれば。
836 :
デフォルトの名無しさん :2007/12/20(木) 01:08:29
比較しなければならない文字列が数千とかある場合だったら、このやりかたは結構うまいと思うのだがどうよ。 数千の文字列と入力文字列を比較するうまいやりかたって標準C++にあるっけ。 よさげなアルゴリズム(←ヘッダ名ではなく一般名詞)でもいいけど、参考までに教えて。
完全ハッシュ関数とか?
838 :
デフォルトの名無しさん :2007/12/20(木) 01:51:11
>>837 完全ハッシュの計算はgperfとかで事前にやっとくとしても、与えられた文字列ハッシュするのって時間かかるんでない?
もっと速い方法無いかな。
839 :
832 :2007/12/20(木) 01:51:49
素直にifでやったほうが無難か。 ちなみに、コンストラクタ呼び出しはプロセス開始直後に数十回程度で、 作ったインスタンスはプロセス終了まで使い回すつもり。
>>836 >>832 の書き方だと、設定時に常に lower_bound が走る上にメモリ確保の回数も多くなるから、
無駄だと思うんだよね。if にくらべてどれだけ高速化するか微妙。
どうせなら、vector に、キーと値のペアを設定して、あらかじめ挿入するサイズを reserve してから
push_back でどんどん追加していき、1回ソートしてから、lower_bound で検索したほうが高速化すると思う。
>>836 使ったことないけどトライとかどうよ。
>>832 はmapを使い捨てるから効率は期待できない。
ただ俺は
>>835 に同意。性能が問題にならないなら書き易い方法を選ぶべき。
map 作るのも vector をソートするのもキーの数 N に対して O(NlogN) になるよね? だったら O(N) でも素直にループで比較するほうがマシなんじゃないの? map やソート済み vector を全部のインスタンスで使いまわすようにすれば、 素直なループより効率よくなりそうではある。
843 :
デフォルトの名無しさん :2007/12/20(木) 12:59:51
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM , Boy *boy); int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { DialogBox(hCurInst, "DLGBOX", NULL, (DLGPROC)DlgProc); return 0; } BOOL CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam , Boy *boy) { char boy[256],ookisa[128],namae[128]; switch (msg ) { case WM_INITDIALOG: //ダイアログボックスの初期化 return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK://OKボタンが押されたら GetDlgItemText(hDlg, IDC_FAIL1, namae, (int)sizeof(namae)); GetDlgItemText(hDlg, IDC_FAIL2, ookisa, (int)sizeof(ookisa)); wsprintf(boy, "名前を%sに、大きさを%sに変更しました", namae, ookisa); MessageBox(hDlg, boys, "変更したぷぃ(>o<)b", MB_OK); strcpy(boy->name,namae); boy->value[64] = ookisa[64]; EndDialog(hDlg, IDOK); return TRUE; } return FALSE; } return FALSE; }
844 :
デフォルトの名無しさん :2007/12/20(木) 13:02:25
上記プログラムでダイアログを作り、文字入力を行い、入力された文字を他の文字に代入したいと考えておりますが、上手く出来ません。何か方法はございませんが? 一応コンパイルまでは出来るんですが、ダイアログボックスに文字、数字を入力し、OKをクリックするとアプリケーションエラーになってしまいます。 どなたか教えていただけないでしょうか?
846 :
845 :2007/12/20(木) 13:31:43
うあアンカーミスった。 >843-844 ね。
847 :
デフォルトの名無しさん :2007/12/20(木) 14:30:43
>>842 「素直にループで比較」の計算量の検討が抜けてない?
>>841 トライ(trie)って、map<string>のred-black treeと比べて
どういう利点があるの?いまいちわからん。この例限定で
いいから教えて。
>>847 単に連想配列として使う場合は、赤黒木の様に平衡を保つ並べ替え処理が行われないので速い。
>>848 じゃぁ、
"aaa......aaa0001"
"aaa......aaa0002"
..
"aaa......aaa9999"
みたいなデータをつっこむとtrieだと遅くなるのかな。
>>849 それだと赤黒木でも相当遅くなりそうだ。
文字列比較のたびに毎回大量のaを比べないといけないからな。
851 :
デフォルトの名無しさん :2007/12/20(木) 15:38:08
ならhash (std::tr::unorderd_map?) かな。でも長い文字列のhashはそれはそれで遅いよな。 うーん。
計ってみた。trieの実装はでっちあげなので余り真に受けないように。 先頭にP文字の'a'があって、それにQ文字のランダム(R種類から選ぶ)な文字が続く文字列を N個つっこんで、10万回検索した。挿入の時間は計ってない。 trie: 4 map: 14 0 10 5000 256 trie: 29 map: 17 0 50 5000 256 trie: 8 map: 25 40 10 5000 256 trie: 2 map: 9 0 10 5000 32 trie: 10 map: 13 0 50 5000 32 trie: 9 map: 18 40 10 5000 32 左から、trieでの時間、mapでの時間、P、Q、N、R。 上から二番目、完全ランダムな50文字の場合を除けばtrieが速いな。 ただし上から二番目ではtrieが相当メモリを使ってて、N=10000では動かせなかった。
855 :
デフォルトの名無しさん :2007/12/20(木) 23:52:10
>>852 挿入の時間も知りたい。平均m文字程度の大量の文字列を高速にソートしたいんだよね。
std::mapに突っ込んでiteratorが速いならそうするし、他の方法があるなら知りたい。
trieとかいうのも興味ある
単にvector<string> s;をsort(s.begin(),s.end())のほうが速かったりする?
それとも何か特殊なデータ構造が適当なのかな
ソート目的ならバランスしてる必要はほぼゼロなんだから、 一般的なstd::mapを使うのは自明な方法の中では最悪だと思うけど・・・
バランスしてないと最悪O(N2)でしょ
STL勉強中で、基本的な質問なんだけど string& func() { std::string s = "text"; return s; } という書き方は正しい?(stringじゃ無くてVectorなんかも同じ?)
859 :
858 :2007/12/21(金) 06:25:32
あれ、VSで動かすとwarning出るんだな。 とにかくfunc()内で動的に生成したstringオブジェクトを返すのは どうすればいい? 普通にnew? それだと解放はいつすべき?
860 :
デフォルトの名無しさん :2007/12/21(金) 06:28:36
普通にnew
861 :
858 :2007/12/21(金) 07:12:38
>>860 どーも。で、解放は何時してやればいい?し忘れても問題ない?
あと、こんなのも駄目なの?
string instr = "text";
string outstr;
copy(instr.begin(), instr.end(), outstr.begin());
>>858 局所変数の参照を返してはいけないのは普通の変数でも
STL系でもすべて同じ。
そのまま実体を返して不都合がなければ string 返しな。
>>861 試してないから間違ってるかもしれんが
copy(instr.begin(), instr.end(), insert_iterator( outstr ) );
だとおも。もしくは先に outstr.resize( instr.length() ); とか。
863 :
858 :2007/12/21(金) 08:46:12
>>862 レスさんくす
VSの混合モードで見ると
>>858 はstringのコンストラクター2回、
デストラクターが1回よばれてる。warningは出るけど、実は問題ないんじゃない?
とか思ったり。
>>861 に関してはoutstrをstringの代わりにstringstream使えばいいみたいだけど、
(insert_iteratorはstringに使えない?)
シンプルな
>>861 のパターンが駄目ってのは美しくないよな。
>>863 問題ある。たまたま動いてるだけだ。
copy使うなら、
copy(instr.begin(), instr.end(), back_inserter(outstr));
だな。
865 :
858 :2007/12/21(金) 09:16:26
>>864 どーも。back_inserterでいけたけど、上のiteratorやbegin()と何が違うんだよ。
866 :
デフォルトの名無しさん :2007/12/21(金) 09:20:05
std::map の erase メソッドって,イテレータではなくて キーを指定して削除する erase(key) のような呼び出しもできますよね? このときマップに key が登録されていない場合には 例外が出るのですか?out_of_range が投げられるのかなぁ とおもってずっと catch して待っているのですが, いまだになんの音沙汰もありません.
867 :
866 :2007/12/21(金) 09:23:46
SGIのドキュメント見たら size_type erase(const key_type& x); Deletes the element with the key value x from the map, if one exists. Returns 1 if x existed in the map, 0 otherwise. でした.どう見ても戻り値です. 本当にありがとうございました.
>>865 insert_iteratorはテンプレート名であって関数名じゃないから、そのまま呼び出すのには使えない。
outstr.begin()を使うと、outstrの要素を上書きしながらコピーという意味になる。
outstrは空なので、上書きしようとしたら未定義動作が起こる。
back_inserter(outstr)なら、「outstrの末尾に追加」だから問題ない。
869 :
858 :2007/12/21(金) 10:47:42
>>868 上書きと末尾に追加を分ける必要があるのかなんだよなー
書き込む対象がstringなんだから、自動で増やしてくれてもいいと思うんだけど。
まぁ仕様の話しても仕方ないのでこのへんで。
>>865 std::copy は *(oitr++) = *(iitr++); を繰りかえしてる。
イテレータを *( itr++ ) = ?; として使った場合に
begin() で得られるイテレータはこんな動作。
*(ptr++) = ?;
back_inserter で得られるイテレータはこんな動作(等価になる)。
container.push_back( ? );
>>869 もうちょっと勉強すれば、なんでそうなっているのかとか、
自分がどれだけ不自然なことを要求してるのがわかると思うよ。
872 :
858 :2007/12/21(金) 11:49:14
>>870 memcpy同様の動作ってこと?
でも本来はストリームとして動作することが期待されるわけで、
内部の実装はどうであれ、取得したイテレーターはシーケンシャルな
アクセスが可能でないと困る。
人間的にはこっちのほうが自然だよ。
領域が勝手に拡張される方が困ると思うけど 無限長のsequenceというconceptを新たに作れと?
>>858 というか、
>>861 が何をしたいのかさっぱり分からん。
outstr.assign(instr.begin(), instr.end())ってこと?
それともinsert?
>>873 「人間的」とか宗教みたいなこと言い出したから、もうこれ以上話が深くはならんだろう。
858にはC,C++は向いていないと思う。
>>872 > でも本来はストリームとして動作することが期待されるわけで、
そのために stringstream なんてものがあるわけだが…
何を期待してるか知らんが string はそもそも char* のラッピングだぜ?
878 :
858 :2007/12/21(金) 13:14:01
いや、ずっとスクリプト系いじってたから
どうしてもSTLみたいなのに高度な抽象化を求めてしまうのよ。
>>873 stringって勝手に拡張されないの?
>>874 練習用なので意味は無い。
>>877 stringが固定長で変化しないっていう仕様なら文句は言っていない。
stringが自動で拡張されることはない。だから string s("foo"); s[4] = 'a'; とかやったら未定義。 operator[]で範囲チェックすらしないほど効率重視の設計だから、 イテレータへの書き込みで自動伸長しないのも自然だと思う。
>>858 string func()
{
std::string s = "text";
return s;
}
なんだ。スレが伸びてると思って期待したのに またC++が難しくてスクリプトに逃げた奴が叩いてただけか。 世間ではもう冬休みかぁ…
882 :
858 :2007/12/21(金) 13:51:39
>>879 じゃぁ
str = "abc" (abcやdefは実際はもっと長い文字列とする)
str += "def"
の場合は内部で再アロケーションするんじゃないの?
858は文字列が何なのか分かってないに一票。
>>882 879は「 operator[] () では拡張されない」ということを書きたかったんじゃないかな。
いまその辺が話題なわけだから。拡張するしかないときには、当然拡張されるよ。
vector や string の operator[] に例えばレンジチェックが入ったら、
使える場面が大分限定されちゃうよね。
「範囲を超えるかもしれないのでチェックしてほしい」というレアな使い方以外では
ポインタやただの配列より強烈に遅いだけでメリット無いんだから。
886 :
デフォルトの名無しさん :2007/12/21(金) 14:29:20
範囲のチェックしたければ at を使えばいい. って,そういう話じゃないの?
std::string::begin()の返すiteratorはrandom access iteratorではあるけども back insert iteratorでないから 一方std::backinserter(Container)はback insert iteratorを返すのでok
888 :
858 :2007/12/21(金) 14:37:35
結局は内部的に
ptr++してる時([]も含む)はレンジチェックは一切行われず、
意図的にデータを追加する処理を呼び出したときのみレンジチェックがされて
足りなければ追加されるってことでいいのかな?
で、copy動作は追加では無く単にptr++動作でしかないために
動的に拡張されず、したがって
>>861 みたいな書き方が出来ないと。
でもiteratorに対して読み込みは出来るが書き込みは出来ないって言う
非対称性はどうも綺麗じゃないと思うな。まぁ思うだけにしておくけど。
back_insert_iteratorはコンセプトじゃねーぞ
>>878 抽象化もなにも、抽象化されたcopyというアルゴリズムの意味をおまえさんが理解していなかった(しようとしない)だけだろ。
C++の<algorithm>ではコピーの本質は
>>870 に書いてあるとおり純粋な情報の移動の
ことで、メモリ割り当てはまた別の話とされている。
どこからコピーするか、どこへコピーするかはイテレータによって抽象化されている。
ストリームとしての動作が当然なんて言う狭い考え方の基には作られていない。
そういう動作が欲しければ、別途そういうライブラリを作るなり調達するなり、
委員会に提案するなりすればいいんじゃないか。copy_back_insertとか(笑)
書き込みできるよ。 std::string in("abc"); std::string buf("uvxyz"); std::copy(in.begin(), in.end(), buf.begin()); /* bufは"abcyz"になる */
じゃback insert iteratorがさすものはback insertion sequenceだから
>>888 > 意図的にデータを追加する処理を呼び出したときのみレンジチェックがされて
> 足りなければ追加されるってことでいいのかな?
いや、back_inserter は末尾に追加するだけ。
レンジチェックもクソもない。「末尾に追加」する。
> で、copy動作は追加では無く単にptr++動作でしかないために
> 動的に拡張されず、したがって
>>861 みたいな書き方が出来ないと。
yes。同様の罠が transform とかにもあるから注意。
> でもiteratorに対して読み込みは出来るが書き込みは出来ないって言う
> 非対称性はどうも綺麗じゃないと思うな。まぁ思うだけにしておくけど。
ダウト。書き込みは上書き扱い。
配列でポインタ使ったときとちょうど対称になるでしょ?
他の言語との対象性は知らんがw
894 :
858 :2007/12/21(金) 14:43:34
微妙に不正確
copy動作は
>>861 のようなコピー動作に限っての話
895 :
デフォルトの名無しさん :2007/12/21(金) 14:46:01
string& func() { :string *s = new string ; *s="text"; return s; } でいいんじゃないの
896 :
858 :2007/12/21(金) 14:51:39
>>890 抽象化という言葉の捕らえ方が俺とは逆だね。
ストリームからストリームへデータを移動させる、ってのが抽象的な表現で
イテレーターがどのような挙動をするかは実装依存。
俺はその実装がどうなっているかわかってないから困ってるのだ。
>>893 いつレンジチェックされるんだろうw
.netのmarshal系なんて
>>861 の書き方に近かったと思うけど。
いやまぁいろいろ勉強になったよ。
STLPortのリファレンスではstd::basic_stringは back insertion sequenceじゃないのでback_inserterの引数にできないはずなんだけど ISO/IEC 14882:2003ではback_inserter(Container)になってる どっちを信用すればいいんだ・・・ってそりゃ規格の方か もしかしてこのリファレンスって信用ならんしろものなの?
898 :
デフォルトの名無しさん :2007/12/21(金) 14:53:25
string& func() { string *s = new string ; *s="hoge"; return *s; }
899 :
858 :2007/12/21(金) 14:54:02
>>895 呼び出し元はfunc()がどのようにstringを確保したか知らない前提とした場合、
deleteは誰がする?
>>895 delete しないでいい処理なんかでは使えるかもね。
なんか言葉が噛み合ってないな。
>>896 str.begin()で取ったイテレータもちゃんとストリームになってる。
このストリームにデータを流し込むのはstrの要素を上書きするのと同じ。
だから、このストリームには流せるデータ数に制限がある。
で、back_inserter(str)で取ったイテレータはこれとは別のストリームで、
これにデータを流し込むのはstrに要素を追加するのと同じ。よって無制限に流せる。
これで一貫してると思わないか?
C++においてストリームって言葉はどう定義されているんだっけ?
「抽象」やストリームもbuzzwordだったんだね
C++でストリームというのはbasic_istreamやbasic_ostreamを継承したクラスのことだから 別の意味で使わない方がいいよ。
「抽象」は皆同じ意味で使ってるだろ。
906 :
デフォルトの名無しさん :2007/12/21(金) 15:13:30
main(){ string a; a.reserve(70000000); string().swap(a); int n;scanf("%d",&n); } で解放できるけど、newと参照の場合は解放できない 消し方は無いのかも
s/ストリーム/Sequence でもいまのところ意味は同じにみえる
908 :
デフォルトの名無しさん :2007/12/21(金) 15:18:27
こっちは解放するけど、 main(){ string a; a.resize(100000000); cout<<a.size(); string().swap(a); int n;scanf("%d",&n); } こっちは解放しない string& func(){ string *s = new string; (*s).resize(100000000); return *s;} main(){ string a=func(); cout<<a.size(); string().swap(a); int n;scanf("%d",&n); }
909 :
858 :2007/12/21(金) 15:21:05
>>901 大丈夫だよw
ただ、別のストリームが登場してくるのがいやだっただけ。
一貫性なら単一のイテレーターでいろいろ出来るほうが楽だと思うが、
実装がパフォーマンスとの兼ね合いでそうなっているならまぁ仕方が無いのかと。
>>904 俺は単に流し込むものくらいの意味で使ってた。
910 :
デフォルトの名無しさん :2007/12/21(金) 15:21:13
これでも無理 string& func(){ string *s = new string; (*s).resize(100000000); return *s;} main(){ string a; a=func(); string().swap(a); delete(&a); int n; scanf("%d",&n); }
911 :
デフォルトの名無しさん :2007/12/21(金) 15:29:00
もとのアドレスがわからなくなるのにちゃんと使えている string& func(){ string *s = new string; cout<<"s="<<s<<endl; (*s).resize(100000000); *s="hoge"; return *s;} main(){ string a; cout<<"a="<<&a<<endl; a=func(); cout<<"a="<<&a<<endl; cout<<a<<endl; int n; scanf("%d",&n); }
912 :
デフォルトの名無しさん :2007/12/21(金) 15:33:13
これでOKだった string& func(){ string *s = new string; (*s).resize(100000000); return *s;} main(){ string *a; a=&func(); string().swap(*a); int n; scanf("%d",&n); }
>>909 「光学センサー付き絶対安全金槌ただし一回振るのに10秒かかる」と「石」、
しかなかったら、釘を打つのには結局は石を使っちゃうでしょう。
だったら普通の金槌を用意するのが妥当、と。
>int n; scanf("%d",&n); これってもしかしたらGUI環境用のおまじない? だったらgetchar()だけで済むだろうに…… つーか、なんか思いっきり勘違いしている気がする。 複数レスに跨っているから指摘するのは面倒だから遠慮するけど。
stringがリークしてるし、こんな糞コード実際に使われたらかなわん
916 :
C++脳 :2007/12/21(金) 17:34:40
GC脳とC脳 ってコワいですね。
>>915 まったくだ、だれがDeleteしてるんだっていうね
918 :
デフォルトの名無しさん :2007/12/21(金) 19:28:55
なんでせめて auto_ptr にしないのん?
919 :
デフォルトの名無しさん :2007/12/21(金) 19:35:53
auto_ptrで解放したら、だめだろう
はいはいstd::tr1::shared_ptr
【今後の流れ】 「規則でtr1使えません><」 「自分で作れカス」
namespace std { using tr1::shared_ptr; }
Glib::RefPtrをですね、
>>896 > 抽象化という言葉の捕らえ方が俺とは逆だね。
そういう問題ではないだろう。
何かを抽象化するときに、視点が違えば別の解になる。
STL は挙動で抽象化してるから、君の視点と違うせいで、おかしな設計に見えるのだろう。
STL の設計思想に慣れるしかない。
むしろアクセスするだけで勝手に拡張されるほうが気持ち悪いと思う・・・ 範囲外アクセスになったときは素直に落ちて欲しいなあ
それなんてmap::operator[] え?find使えって?
927 :
858 :2007/12/23(日) 09:52:22
>>924 抽象化に視点はあまり関係ないと思うぞ。
上での例を使うと、copyという操作は概念としてAからBへデータを複製することになる。
そして、copyという語自体、それ以上の意味を持っていない。
しかし、C/C++のmemcpyなどでは
・コピー元A、コピー先B共にメモリ上のデータであること。
・コピー先Bに必要な領域が確保されていること。
という条件が付く。(memcpyの仕様)
そして、上のほうで書いたcopy操作もmemcpyと同じ条件が付く(ので合ってるのか?)
これは抽象的概念を具現化する過程で(つまりは実装すること)
その実装方法によりいくつかの条件、制限が付加される。
視点が違うと感じられるのは、この実装過程での思想の違いによるものでしかない。
だから各条件に応じて数種類のイテレーターを使い分けなければいけなくなる。
抽象化というのは、このような条件、制限を出来るだけ撤廃してオリジナルの
概念をあらゆる場面で適用出来るようにすること。
たとえば、copy fileA, fileBを実装する場合、Bが自動的に拡張されないように
実装したら馬鹿だと言われるぞ。
928 :
858 :2007/12/23(日) 10:04:48
なので、条件、制限がある場合はそれが適切に分かるような関数名にすべきだと思う。 シンプルな関数名はシンプルな動作が期待されるわけで、その関数がどのような実装で あるのか知る必要もないくらい、あらゆる場面で使用できるってのが理想的。
>>927 >そして、上のほうで書いたcopy操作もmemcpyと同じ条件が付く(ので合ってるのか?)
合ってない。例えば標準入力を標準出力にコピーする操作もcopyで書けるけど、
この操作はどちらの条件も満たしていない。
自動的に拡張されないのはstringの仕様(もっといえばstring::beginの仕様)であって、
copyはそんなことには関知しない。
string::beginの仕様じゃなくてstring::iteratorの仕様と言った方が適切だな、すまん。
>>927 > 抽象化に視点はあまり関係ないと思うぞ。
設計によってインターフェースが違ったりするよね?
それを、抽象化の視点が違うから、と説明するのはおかしいと思う?
例えば GUI の実装がいくつもあって互いにかけ離れたものがあるけど、同じように抽象化したのにインターフェースが別物になったと思う?
なら、抽象化という単語の意味を取り違えていると思うよ。
俺は、挙動を iterator で分類する抽象化はなかなかいいと思うけどね。
> 上での例を使うと、copyという操作は概念としてAからBへデータを複製することになる。 > そして、copyという語自体、それ以上の意味を持っていない。 わかってんじゃん。 それなのになぜ、 > そして、上のほうで書いたcopy操作もmemcpyと同じ条件が付く(ので合ってるのか?) なんてトンチンカンなことが出てくるのかがわからん。 そんな条件は無いし、ましてやコピー先が自動的伸縮できることという条件も無い。 そんな制限があったら使えるシチュエーションが限られてしまうじゃないか。 それは実装の詳細だから包み隠されているべきと言うだろうが、 それはあるレイヤーの上にいる人の視点。 その実装の中にも設計があることをお忘れ無く。 伸縮するバッファを実装する人がcopyを使えなくなってしまうでしょ。
933 :
デフォルトの名無しさん :2007/12/23(日) 11:53:53
stl:set って挿入するときに「同じ値」だと挿入されないですよね? その「同じ値」って言うのは operator < だけで判定してるんですか? それとも別途 operator == が定義されていなくてはだめですか?
<だけ。
iteratorの中の人
>>933 !( a < b ) && !( b < a ) なら a == b
937 :
858 :2007/12/23(日) 12:59:50
>>931 言っていることがよくわからん。
プログラム的な抽象化ってのは、一度細分化された後で
同様の概念を持つものを再統合するようなイメージ。
インターフェイスの違いなどはまだ細分化されたままの次元において出てくる話。
なのでそういう部分を指して話をするのであれば、抽象化の話とは違うと思う。
>>932 本当にcopyに関しては何も条件は無い?
イテレーターの正体がメモリのポインターであっても、ファイルポインターであっても
STLのコンテナであっても?
そして全て同様の動作が期待されると考えてよいの?
>>870 は間違い?それともイテレーター次第?イテレーターに依存するのであれば、
それも条件のうちだよ。
>それはあるレイヤーの上にいる人の視点。
逆に言えばC++の人はそういう細かい実装中心で思考してるわけで、
そもそも俺が言っている条件のようなものは空気のようなもので
普段は意識してないのかもしれない。
自然言語上での抽象化なんて誤解の元でしかないということだけはわかった
939 :
858 :2007/12/23(日) 13:12:20
そうそう、結局知りたかったのは、ライブラリがどのように実装されているかを 知っているということがSTL(boostも)を使いこなす前提となっているのかどうかってこと。 知らないよりは知っているほうがいいだろうが、実装を知らないまま使うことが 不可能に近いレベルで無理なのか?というところを知りたい。
実装は知らなくてもいいけどconceptを知らないとtemplateを使えない
実装を知らないと何に使うのかわからない、というようなことはあるかもな。 dequeとか。
c++初心者用で聞けば良いのか迷いましたがSTLを使っているためこちらで質問させていただきます。 あるクラスPointがあり コンストラクタは2つの引数を受け取るものです。Point(int x,int y){・・・} vectorを使用してPointクラスのポインタのリストを作成したいのですが どのようにすればよいのでしょうか?よろしくおねがいします。 以下 厳しい突っ込み覚悟のメモ書き vector<Point *> test; ↑もし このような形であっているとしたら、その後、値を入れるにはどうすればよいのでしょうか? test@push_back(@); ↑一応このような形かも とは考えて見ましたが(@はどうすればいいのか検討もつきませんorz)
>>937 copyが内部で
*iter++ = ???;
みたいな操作をやってるってのは実装の詳細でもなんでもなくて、copyのインタフェースの一部だ。
そもそも出力イテレータというのは、*iter = ???の代入が意味を持つ型のこと(もうちょっと制限があるけど)で、
copyというのはこの操作を入力イテレータが指す範囲のそれぞれの要素について行うものと定義されている。
ただし、copyの内部が
*iter++ = ???;
なのか
*iter = ???;
iter++;
なのか
*iter = ???;
++iter;
なのかは本当に実装の詳細だけどな。
test.push_back(new Point(0, 0));
>>945 今はcopyの実装が実際にどうなってるかを問題にしてるわけじゃなくて、
copyの実装をどこまで知っている必要があるかの話をしている。
たとえ後置++を使ったcopyの実装があったとしても、正しい出力イテレータを与えれば
前置++を使ったcopyの実装と同じ挙動を示すというのが重要。
947 :
858 :2007/12/23(日) 14:09:24
>>943 いや、そうでなくて。
少なくとも*iter++と書くこと自体、メモリ上のポインターであることを前提としている。
イテレーターがファイルのポインターだとすると
概念的には
file[filepos++] = ???
のように表せるはず。
(内部の実装では当然メモリ上のコピー動作は発生するが、
その後ファイルへの書き込みまで行って操作が完結するので
実装を全く意識せずに表すとこうなる)
だから、本当にメモリのポインター操作しか行わないのか
上記のような高度な操作もしているのかどうかということ。
もし、メモリ上のポインターのみであれば、それは実装を意識していることになるんだけど。
>>947 >少なくとも*iter++と書くこと自体、メモリ上のポインターであることを前提としている。
してないよ。
この式には二つの演算子(後置++と前置*)が出て来るけど、どっちもオーバーロードできる。
ファイルへの書き込みを行うイテレータなら、
*iter++ = ???;
と書いたときに、内部的に
file[filepos++] = ???;
を行うようなオーバーロードを行なっている。
とりあえず俺は中身を知った上で毎回同じことを書く手間と それに付随するニアミスを防ぐためにライブラリを使うものだと思ってる。 中身を知る労力すら惜しい輩は一生 ruby でも書きなぐってればいいのに。
そこはJavaと言っとくべきじゃないか、C++的には。
>>949 別に知らなくても使えるんだから、そうやって使いたい奴が使うのを止める理由はないじゃん。
*iter++ができるということはinput iteratorとしての用件をみたす ちなみにpointerはrandom access iteratorとしての用件をみたす
要件
954 :
858 :2007/12/23(日) 14:30:16
抽象化がちゃんと機能していれば特定機能を持つキーワードを繋げていけば どのようなオブジェクトでも処理ができるので、その方が物作り的効率はいいんだよね。 実はrubyで特定処理が遅いからC++化しようとしてるだけだったりするw
>>954 >>948 は無視か?
とりあえず
>>858 にC++を教えた奴(か書籍)は、
イテレータがそもそも++と*で成り立ってるってことを紹介するべきだな
# include <iterator>
# include <iostream>
int main(void)
{
std::ostream_iterator<int> oi(std::cout, "\n");
*oi++ = 1;
*oi++ = 2;
*oi++ = 3;
}
956 :
858 :2007/12/23(日) 14:33:43
実装知らずに使ってみて、何回も頭ぶつけるから仕方なくソース見てるってのがホントじゃない? boostまで理解しようとしたら、みっちりやって半年か1年くらいかかりそうだ。
そもそも string に stringstream の機能を求めるような人に 抽象化が機能してるとかしてないとか言えるのかと。 ただ知らない、分かってないだけじゃないかと。 まぁ、何でも混ぜるrubyの弊害なのは分かるんだけどさ… 初心者にとっては機能の単位が分かりづらくなるから あんまり勉強には向かないんだよなぁ。
>>956 プログラミングってそうやって習得するものじゃないの?
959 :
858 :2007/12/23(日) 14:39:13
>>955 見落としてたよw
ファイルの扱いに関しては理解した。
後はまた元に戻るけど、copyのようにイテレーター間のデータの移動についてはどう?
ファイルストリーム→string
vector→list
のようなコピーも定義されてるの?
>>959 それも全部copyでできる。
追記か挿入か上書きかで出力イテレータを使い分けるのも同じ。
961 :
858 :2007/12/23(日) 14:47:04
>>960 なるほど、てことはイテレーターの使い分けが肝であり、
そのイテレーターが何故複数存在しているか理解すれば一番早いと理解してOK?
て言うかイテレーター含め型多すぎだよ。
962 :
858 :2007/12/23(日) 14:50:08
>>957 stringとstringstreamが独立して必要な理由を教えてもらえるとありがたい。
実装上の都合という理由以外で。
stringって変更不可なオブジェクトでは無かったと思うけど。
というかなんか
>>959 は誤解してるっぽいな。
個々の対象(ファイルストリームとかvectorとかstringとか)のそれぞれに、
専用のcopyが定義されてるわけじゃないぞ。
copyの実装は一つで、ひたすら
*出力イテレータ++ = *入力イテレータ++;
のようなことを繰り返すだけのものとして定義されてる。
どこに書き込むか、どうやって書き込むか(追記か上書きか、とか)を知っているのはイテレータだけで、
それに応じて++と*をオーバーロードしている。
>>961 うん、それでいい。
あと、練習としてアルゴリズムを一つ書いてみたら良いと思う。
入力を一つおきに捨てながら出力にコピーするskip_copyとかどうだろうか。
で、それがファイルにもstringにもlistにも適用できることを確認する。
964 :
858 :2007/12/23(日) 15:10:39
>>963 ありがとう、感覚的にかなり分かってきたような気がするw
イテレーターが独立してクラス化されてる理由もなんとなくわかった。
>>962 > stringとstringstreamが独立して必要な理由を教えてもらえるとありがたい。
両者が概念からして全く別のものだから。
というか、文字列を扱うということ以外に共通点が見つからないんだけど。
966 :
965 :2007/12/23(日) 16:19:12
補足。 string は文字列を”保持”して”扱う”ためのもの。 stringstream はクラス階層を見ても分かる通り、 そもそも「データを流し込むもの=stream」であって、 流し込む対象が文字列なだけ。 対象がファイルになると iostream になるし。
std::back_insert_iteratorのvalue_typeやreferenceがvoidなのは何故ですか? vc8ではreferenceはcontainer::referenceになってましたが
968 :
858 :2007/12/23(日) 16:53:40
>>966 うそ臭い説明だなw
じゃぁ単なるstringはストリームとしての特性を全く持っていないのか?
先頭から1文字ずつアクセスできるし、文字列の後ろに文字を追加することも出来る。
cout <<に対して出力も出来るし、stringのイテレーターからの>>も出来たんじゃなかった?
stringもストリームとしての要素は持っていることになると思うけど。
たとえば、stringオブジェクトは1度作ると変更できない、というような特性があるのなら
別のストリームオブジェクトが必要になるのは分かるが、そうでは無い。
だから、やはり単にstringstreamがstream系のオブジェクトを継承しているかどうかに
拠るというのが理由で、実装上の都合のように見えるのだけど。
>>968 > じゃぁ単なるstringはストリームとしての特性を全く持っていないのか?
yes
> 先頭から1文字ずつアクセスできるし、文字列の後ろに文字を追加することも出来る。
配列も先頭から1文字ずつアクセスできるけどストリームか?
mrealloc で配列の後ろに追加できるけどポインタもストリームになるのか?
> cout <<に対して出力も出来るし、stringのイテレーターからの>>も出来たんじゃなかった?
int も cout に << できるけど int ってストリームか?
つまり、ストリームの理解が間違ってる。
970 :
858 :2007/12/23(日) 17:14:40
「データを流し込むもの=stream」 って言ったのはそっちだよw その定義であれば、配列もintもストリームだし。(ストリーム化可能と言うべきか)
>>970 > 「データを流し込むもの=stream」
> って言ったのはそっちだよw
どういう理解をすればああいうレスが出来るのか不思議…
cout << var1 << var2 << var3・・・
^^^^^
こういう風にデータを流し込むことができる対象ってことなんだけどなぁ。
なんか不毛な揚げ足取りになってるな。 まずstringはコンテナだというデザインを受け入れないと何でもアリになるんじゃ?
stream(流し込むもの)ってのは流し込めることが重要なんであって、 流し込む先がどうなるかについては言及していない。 stringの+=は「末尾に追加する」の意味であって、「流し込む」わけではない。
974 :
858 :2007/12/23(日) 17:47:27
>>971 あーすまん、流し込むもの→流し込む対象のものって意味なのか。
さすがに次スレまで引っ張るつもりは無いのでこのへんで。
>>974 あー。「流し込む”もの”」ってことか。
なるほど。そういう誤解されるとは思いつかなかった。スマン。
どう考えたらそう誤解になるのか不思議だ cout, cinの使い方考えたらわかるだろうに
977 :
858 :2007/12/23(日) 18:08:11
いや、特性上どう違うのかっていう説明はもらってないし 極端な話、vectorクラスで<<をオーバーロードしちゃえば vec << newobject なんて書き方も可能だよ。違いはそういうところじゃないはず。
ストリームもイテレータもプロトコルなんだよ。個々の事物で考えようとするからいけない。
さて、もういい加減に次スレは要らないよね?
5ヶ月も満たないうちに一スレ消費するほどのスレを存続させないとはこれ如何に?
立ててくる
無理だった
>>980 C++相談室でやればいいってことだよ。
C++でストリームと言ったら、std::basic_ios<>の派生クラス。 std::stringstreamは、std::basic_stringstream<char>のtypedefで、 basic_stringstream<>は、その基底クラスを辿っていくとbasic_ios<>に辿り着くのでストリームである。 つまり、 > だから、やはり単にstringstreamがstream系のオブジェクトを継承しているかどうかに > 拠るというのが理由で、実装上の都合のように見えるのだけど 俺もこうだと思う。stringに、ストリームにする皮を被せたのがstringstream。
俺は前みたいにC++テンプレート全般を扱うスレッドのほうがいいなと思っている。
久しぶりに見てみたらなんだよ このおバカ全開な流れは
嫌なら黙って閉じればいい
>>984 どうもその説明に違和感がある。
stringを包んでいるのはstringbufで、stringstreamはストリームバッファとして
stringbufを使っているだけにすぎん。
>>988 同意。
HDD の代わりに string を使ってる iostream みたいなものだと認識してるが。
990 :
984 :2007/12/23(日) 20:40:15
988にも989にも同意なんだが、 つまり俺の説明がへたくそなだけだ。すまん
map使ってDB作りました
multimapを比較関数オブジェクトを使って multimap<int,string,greater<int> >と宣言するとエラーが起きるのですが なぜなんでしょうか? なぜかtypedefするとコンパイラを通ります。
typename な気がするが、"そんな初歩的なミスなわけねーだろ! 肉球ぷにぷにして悶え氏ね"ってんなら、環境とか処理系とかエラーメッセージとか書くべき。
遅ればせながら
>>944 の方ありがとうございました。
995 :
992 :2007/12/23(日) 23:29:28
a.cpp: function 内の `int main(int, char**)': a.cpp:41: error: no matching function for call to `std::multimap<int, std::string, std::greater<int>, std::allocator<std::pair<const int, std::string> > >::insert(int&, std::string&)' C:/mingw-jp/include/c++/3.3.3/bits/stl_multimap.h:326: error: candidates are: typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const _Key, _Tp>&) [with _Key = int, _Tp = std::string, _Compare = std::greater<int>, _Alloc = std::allocator<std::pair<const int, std::string> >] C:/mingw-jp/include/c++/3.3.3/bits/stl_multimap.h:350: error: typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::iterator, const std::pair<const _Key, _Tp>&) [with _Key = int, _Tp = std::string, _Compare = std::greater<int>, _Alloc = std::allocator<std::pair<const int, std::string> >]
>>995 insertの呼び出しが間違ってるだけのように見えるが。
お馬鹿全開かつ痛い流れのような気がして見てなかったけど、 もしかしたら見落としてる基本が掘り起こされてるかもしれないから、おさらいしておくことにする。 何も掘り起こされてなかったら、次スレで何も無かったようにROMる。 新たな発見があったら、、恥かしいからやっぱ何事も無かったかのようにROMる。 そして、酔っ払ってるから今日は寝る。
998 :
858 :2007/12/24(月) 03:45:15
てめぇでだいぶ消費したんだから当然だ スレ立て乙
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。