【C++】STL(Standard Template Library)相談室 8
1 :
858 :
2007/12/24(月) 03:41:59
2 :
858 :2007/12/24(月) 03:42:34
3 :
858 :2007/12/24(月) 03:43:17
4 :
858 :2007/12/24(月) 03:43:53
5 :
858 :2007/12/24(月) 03:44:36
8 :
デフォルトの名無しさん :2007/12/24(月) 16:19:16
std::pair のインスタンスから first および second を 取り出すファンクタは std の下に用意されていますか? boost::tuples::get<0> みたいなやつを探しています. 自分で定義してもいいんですが,標準的な方法が 用意されているのであればそちらに従いたいと思います.
9 :
デフォルトの名無しさん :2007/12/24(月) 16:32:24
>8 確か標準には無い。 g++だと、#include <ext/functional> して、 __gnu_cxx::select1stとかselect2ndが使える。
mem_funのメンバ変数版とかないの?
boost::mem_fn
ベクタコンテナを初期化子で初期化する場合 vector<int> vec; Foo::Foo() : vec() {} こうしてるんだけど、間違ってない?
間違ってはいないけど、要素数0で初期化なら何もしなくてもいい。
>>13 サンクス
そこが聞きたかったんだけど、vectorは初期化しなくても使えるのは知ってたけど
どのタイミングで、初期化を行ってるの?
vector型のインスタンスが作成される、手前で初期化をにやってると想像するんだけど
コンストラクタが呼ばれるだけですが
>>15 なるほど、コンストラクタが呼ばれたら、そこで初期化が行われる仕組みになってるんだ
納得シマスタ
どんだけ〜
コンストラクタは何の為にあると思ってたんだろう
20 :
デフォルトの名無しさん :2007/12/25(火) 00:12:46
件のvectorのコンストラクタで質問なんですが、 vectorのオブジェクトを生成するとメモリ割当て子を一つ生成してさらに割当て子を2回コピーしてるようなんですが、 なんでvectorは合計で3つも割当て子のオブジェクトを用意してるんですか?
その挙動はコンパイラの実装次第だから何ともいえない。
先頭ポインタ、末尾ポインタ、メモリ確保領域の末尾ポインタの3つ。
割当て子ってアロケーターの事だと思った。
24 :
20 :2007/12/25(火) 00:31:57
レスありがとうございます。 もう一度コードを読見直してみます。
見直すってvectorの実装をか?勉強のためなら止めはしないが・・・ その実装がどの環境でも同じかどうかなんて保障はないぞ。 別にお前さんは何も間違っているわけでもなく、そういうものだと理解するんだ。
20の場合では、コンストラクタの既定引数の実引数として1つ作られ、 そこから仮引数へのコピー、そこからvectorのメンバ変数へのコピーで2回だろうな。
vector<int> vec; 〜 vecに対する処理(入れたり、出したり) 〜 if( !vec.empty() ) erase( remove( vec.begin(), vec.end()) ); コンテナの要素が空でない場合、要素を全削除する関数ですが、これをtemplateに してもらえませんか、宜しくオナガイシマス
>>27 erase() とか remove() とかの使い方がおかしくてよくわからんけど、
それは無条件で全削除する、つまり vec.clear() と何が違うの?
template にすると言われても何をテンプレート引数にするのか決めないと
どうにでもできてしまうよ。 template<int N> ... とか。
>>28 サンクスです
vecの型が
vector<double> vecであってもvector<string> vecでも
削除できるようにしたいのですが?
ごめんなさい erase( remove( vec.begin(), vec.end()), 削除したい特定の要素 ); でした
>>29-30 情報小出しの兆候が見られて嫌な感じだな。
いくらかわかったけど、細かい仕様がわからないから何ともできない。
たとえば関数テンプレートにしたいんなら関数の戻り値や引数がわからない。
とりあえず自分で書いた奴みせて。
>>29-30 こうですかわかりません
template<typename T>
void erase_it(vector<T>& vec, const T& value)
{
vec.erase( remove(vec.begin(), vec.end(), value), vec.end() );
}
まだ続々と新情報が出てくるだろうから しばらく適当にイジってたほうがいいと思うよ
>>27 です
夕べは眠くて、質問を書き間違えました
>>コンテナの要素が空でない場合、要素を全削除する関数ですが、
これが間違いで
vector型のコンテナで、特定の要素を削除できる汎用的な(Template)の書き方が
教えて欲しかったのです
ですので、32さんありがとう
27です、32さんに教えてもらって、Templateの書き方が何となく分かってきた 気がします、連投で申し訳ないけど コンテナの空チェックで vector<int> vec; if(!vec.empty()) vec.clear(); 〜空で無い場合の処理 この様な書き方をすると思うのですが、Templateにした場合 この書き方は間違っていますか? template<typename T> void empty_it(vector<T>& vec) { if(!vec.empty()) vec.clear(); }
つーか、vec.clear()だけで充分ですが。
>>36 空のコンテナを
vec.clear()すると
アクセスバイオレーションになりませんか?
なんでそんなことになると思うの?
以前、空のコンテナをclear()したら、そうなった気がしたんですが 今手元に、コンパイラが無いんで確認できないんですが、 勘違いだったのかなぁ・・・
>>40 ってことは、空のコンテナをclear()しても、問題は無いってことですか?
やはり
>>35 の処理は不要ってこと?
>>42 了解したよ
ありがとう、幾ら簡単な例ができても、何の役にも立たなくては、意味無いからね
解決した途端、敬語が消えてどっかの審査員みたいな目線になるのは GoFでいうとなにパターンですか?
pimpl
Observer
47 :
デフォルトの名無しさん :2007/12/29(土) 01:46:38
vector::insert()で、 insert(先頭位置, 挿入数, 挿入する物) insert(先頭位置, 挿入する物.begin(), 挿入する物.end()) というバリエーションがあるみたいなのですが、どういうバリエーションがあるかは どうやって知るのでしょうか?manページとかがあるのでしょうか?
49 :
デフォルトの名無しさん :2007/12/29(土) 02:07:58
俺が今仕事で使ってる環境にはstdc++のmanが入ってるな。 ただ所々間違ってるんだけどw std::mapのerase(iterator position)がpositionの次のiteratorを返すって書いてあったりする。
51 :
デフォルトの名無しさん :2007/12/29(土) 11:30:15
そういや
>>47 のようなことを思っていた時期もあったけど,
いまや IntelliSense に頼りっきりになってしまった.
そろそろ趣味グラマで Linux 上でのプログラミングも
しようかと思うんだけど,Emacs でそういう補完とか
やろうと思うとどんな *.el 入れれば便利なんだったっけ?
Linuxとかならglobalかな emacsには標準でついてる
typedef struct ST_TABLE { int num; int headdate; int taildate; ST_TABLE( ) : num(0), headdate(0), taildate(0){} }ST_TABLE; このような、構造体を持つvector型のコンテナから、for_eachを用いて headdateの最大値を求める、Templateの作り方を教えてもらえませんか vector<ST_TABLE> containerIndex containerIndexには、要素が入っていることと仮定して for_each( containerIndex.begin(), containerIndex.end(), &head ); template<class T> int head(const vector<ST_TABLE>::iterator T& t) { ここまでは分かるのですが(間違っているかもしれない。。。。多分間違ってるでしょうorz)
間違ってます。3引数のstd::max_elementを使いましょう。
これでは、エラーが沢山出てしまうのですが... for_each( containerIndex.begin(), containerIndex.end(), head ); template<class T> int head(const vector<ST_TABLE>::iterator T& t) { return max_element t->headdate; t++; }
max_element(v.begin(), v.end());
>>56 だけど
できちゃったけど、オーバーロード使って、でできちゃったww
templateでは、できないものかなorz
templateで、の意味がいまいち不明だけど、max_element(begin, end, comp)使えって。
61 :
デフォルトの名無しさん :2007/12/31(月) 10:52:36
vector<int> v, w; があったときにvからwへcopy_ifするとき、wの要素の方が少ないとクラッシュするのですが、 そういうときにもwを拡張しながらcopyするにはどうすればいいですか たとえば copy (v.begin(), v.end(), w. begin(), even()); 解決方法としてはv.size()であらかじめw.reserveしておくといいのですが、 vは巨大な配列でwは小さいので余計な領域を予約しまくるのが気持ち悪いです
自己解決しました。 copy (v.begin(), v.end(), back_inserter(w), even()); ありがとうございませんでした。
それだと不必要に非効率になるかも。 w.reserve(w.size() + v.size()) で必要な分のサイズを確保してから、 w.insert(w.begin() + w.size(), v.begin(), v.end()) とやったほうが、 多分(←重要。真相は調べるべき)効率が良い。
reserveするだけじゃ実行時エラーになるかも
vector<int> vec1 vector<int> vec2 vector<int> vec3に vec1の要素1,2,3,4,5,6,7,8,9,10 vec2の要素4,5,6 とします、vec1とvec2をマージして、重複値を持たないように vec3の要素1,2,3,4,5,6,7,8,9,10 としたいのですが、↓これだと merge( vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), back_inserter ( vec3 ); unique( vec3.begin(), vec3.end() ); vec3の要素1,2,3,4,5,6,7,8,9,10,4,5,6 となってしまいます どうしたらいいですか?
uniqueって、remove_ifなんかと同等のインターフェースで、 vec.erase( remove_if( vec.begin(), vec.end(), cond), vec.end() ); みたいな構成にしないとだめ、じゃなかったっけ。
STLじゃないけど #include <cassert> #include <pstade/oven/equals.hpp> #include <pstade/oven/uniqued.hpp> #include <pstade/oven/merged.hpp> #include <pstade/oven/initial_values.hpp> #include <vector> int main() { using namespace::pstade::oven; using namespace std; vector<int> A = initial_values(1,2,3,4,5,6,7,8,9,10); vector<int> B = initial_values(4,5,6); assert( equals(A,A|merged(B)|uniqued) ); } こんな感じでいちいちeraseだの使わずに書きたい気分
>>65 だけど
あのぉーすみませんが、pstadeってなんっすか?
boostライブラリィの一種?
p_stadeさんの作ったC++ライブラリ
かなりマニアティックなものなんですか? 解答が無かったんで、今自力でtemplate作ったけど、速度がでねぇ〜 参ってるんだよね、コンテナ二つがそれぞれ500件と5000件で先の要件を満たす ようにすると、PCが1,2秒固まるんだよね p_stadeさんの作ったC++ライブラリって速度速いの? template < typename ForwardIterator > ForwardIterator to_unique( ForwardIterator lhs, ForwardIterator rhs ) { ForwardIterator result = lhs; for( ForwardIterator it = lhs; it != rhs; ++it ){ if( std::find( lhs, result, *it ) == result ){ *result++ = *it; } } resulturn result; }
sort→unique→eraseじゃないの。これが遅いからどうにかしたいって話か?
俺の環境(athlon64 3000+,gcc4.1.2,linux2.6 x86)ではstlのを1とするとovenは10、
>>70 のは40ぐらいの時間だった
libstdc++でのuniqueの実装はadjacent_findで先頭部分で既にuniqueになってるものを飛ばし
あとはuniqueになっている部分の末尾と比較しながら
uniqueであるなら末尾の次にコピー、そうでないなら無視といった具合に
イテレータが進んでいくだけってシンプルなものだったから、それと比較したらまぁそんなもんかとはおもうけど
2.3秒かかるってのはstd::vectorのreserve()をせずにどんどん突っ込んだとかそういう要因の方がでかそう
p_stade(笑)
75 :
デフォルトの名無しさん :2008/01/02(水) 03:41:11
>>70 >解答が無かったんで、今自力でtemplate作ったけど、速度がでねぇ〜
for文の中でfindしてりゃそりゃ遅いだろうよw
ハッシュつかえば一発じゃん。
76 :
デフォルトの名無しさん :2008/01/02(水) 10:38:22
「ハッシュ」て、ハッシュドビーフのハッシュですか?
はい
ハッシュド、即ちハッシュキーに変換されたビーフ。
お前の話はつまらん
>>76 つまらん話のおかげでシチューを
火にかけっぱだったのを思い出した。
マジ感謝。
# 正月2日からレトルトってのもアレだが。
>>80 レトルトかよ!
時間とれる時くらいまともな料理しろって。(実は喰い物作るのって上手なスレッド処理みたいで面白いのだ)
>>81 分かるw
コンロが複数あると加熱で複数スレッドとか、火入れてる間に別の一品の下ごしらえとか。
慣れてくると俺OSがマルチスレッドに最適化されてくるのが分かる。
生活板か料理板か喪男板かダム河川板でやれ
ダム河川板とのつながりを理解できない俺は負け組み。
86 :
デフォルトの名無しさん :2008/01/03(木) 08:54:14
定数を返すファンクタってありませんか? って自分で書くのは簡単ですが, 標準があればそれを使おうと思います.
87 :
デフォルトの名無しさん :2008/01/03(木) 09:50:18
88 :
デフォルトの名無しさん :2008/01/03(木) 11:07:20
メイヤーズ先生の本を読んで、STLとマルチスレッドって相性悪いと言うか、 結局、期待通りの動作は、実装依存で全てのSTLの振舞いが保障されてないみたいなことが書いてあったな STLを駆使した、マルチスレッドプログラミングって、かなり精通しないと難しそうな印象を持った
90 :
デフォルトの名無しさん :2008/01/03(木) 21:33:28
C++0x でスレッド関係のライブラリが標準で入るようになれば 改善されると期待してるんだけど,無理かなぁ.
>>その本ではどう動く事を期待してたの? Effective STL本に書いてあるのは STLのコンテナでマルチスレッドをサポートする基準、ようするに、実装から 最大限望めることは ★複数の読み取りが安全である ★異なるコンテナへの複数の書き込みは安全である 以上で全てと書いてあるよ、ただし。「望むこと」はできるが、常に実現できるとは 限らないことに注意しなければなっらない。こうした内容を保障する実装もあり、保障しない実装もある。 とのことです、漏れ自身、STLを使ってない、マルチスレッドの実装をリファクタリング∩改造したことはあるけど、 STL∩マルチスレッドの経験ないからあんまり良く分かんないけど、なんか考えても難しそうな希ガスる。
>STLとマルチスレッドって相性悪いと言うか うわさではよく聞くんだけどさ・・。具体的にこの場合に絶対におかしくなる ってコードとどのSTL実装かを知ってる人っているのかな? いまどきのLinuxとかWinでは問題ないとか勝手に思ってるんだけどさ。。
続き。以前にSolarisのSTLでクラス変数をがんばってpthread_lockで 囲ってる実装を見て、なんかあぶなそうだなあと思った記憶はある。
95 :
デフォルトの名無しさん :2008/01/03(木) 22:44:08
libstdc++については、"XXX MT"でgrep してみるといくつか既知のバグがあることがわかるよ。 文字列の参照カウントまわりとか。詳しくはbugzillaをどうぞ。
>>93 >>いまどきのLinuxとかWinでは問題ないとか勝手に思ってるんだけどさ。。
その本にも、同じようなことが書いてある
マルチスレッドプログラムの作成は難しく、STLの実装が最初から完全な
スレッドセーフであればと願うプログラマーは多いと
また、後先逆になったけど
>>具体的にこの場合に絶対におかしくなる
>>ってコードとどのSTL実装かを知ってる人っているのかな?
具体的なミューテックスを、行う際の完璧な(著者いわく)Lock方法が載ってるよ
後、STL以外のマルチスレッドの実装方法は難しいので、それに関しては ビョーン本と、自分の書いた(メイヤーズ先生)MoreEffective C++を 読めとも書いてある
std::stringとかがCOWな実装ならロックしててもまずいよね場合があるよね。
そうだね。詳しくはMore Exceptional C++嫁という感じかな。 翻訳されてないけど。
100 :
デフォルトの名無しさん :2008/01/06(日) 20:55:32
日本語でおkとなった
これだから関数型言語のひとつも使えない連中は以下略
104 :
デフォルトの名無しさん :2008/01/10(木) 23:19:46
a
b
106 :
デフォルトの名無しさん :2008/01/11(金) 14:01:47
初歩的な質問で申し訳ないのですが class sample{ public: vector<int> vector_int; list<double> list_double; 〜省略〜 } というようなクラスをnew演算子で動的に生成した場合、delete演算子で解放 する際にはメンバのvectorやlistのメモリも解放されるのでしょうか。 ご教授お願いします
107 :
デフォルトの名無しさん :2008/01/11(金) 14:11:45
108 :
デフォルトの名無しさん :2008/01/11(金) 14:18:33
>>107 ご教授ありがとうございます。
また質問で恐縮なのですが関連して、メンバを
vector<int> *p_vector_int
とし、コンストラクタ内で動的にメモリ確保したとすると、この場合はデストラクタ内
で解放するように定義しとかなければいけないのでしょうか?
109 :
別人 :2008/01/11(金) 14:42:35
>>108 そのとおり、でも
sample a;
sample b = a;//もしくはsample b(a);
これでデストラクタが呼ばれると同じポインタを複数回deleteしたりする未定義動作になるから注意してね。
>>108 コンテナをnewするなんて糞みたいなことはやめたまえ。
>>109 >>110 ありがとうございます。
確かにコンテナをnewで確保するっていうのも変な話かも知れないです。
動的なメモリ確保・解放っていうのがintやdoubleといったような基本的な
型でしか情報が見つからなかったので、クラスや可変長配列の場合どうなるのか、
モヤモヤしていたんですが、すっきりしました。ありがどうございました。
112 :
デフォルトの名無しさん :2008/01/11(金) 15:05:27
>>108 解放忘れが気になるなら,
std::auto_ptr を使うといいよ.
auto_ptrなんて落とし穴満載の使いづらいのを進めるなよ。
>>114 そこらへんは、自分で判断しますので大丈夫ですよ・・・きっとw
>>108 boost::shared_ptr (or boost::scoped_ptr)
boost::shared_ptr<std::vector<int> > sp_vector_int;
>>111 動的確保する為のコンテナを、動的確保なんて「例」だとしても阿呆過ぎる。
大量に複数のコンテナを用意する場合、コンテナのメンバ変数に メモリが圧迫されることがあるので、newするケースもあると思うがなぁ。
Container<Container<Type> >
120 :
デフォルトの名無しさん :2008/01/11(金) 15:49:21
>>114 だって,boost のビルドからしろって勧めるのも気が引けるじゃないか.
>>120 いや、なるべくbestの回答をするのが親切だと思う。
boost::shared_ptrはboostの他のライブラリに依存しない設計方針らしい
ビルドが必要なのは実装依存のコンポーネントだな。 thread関連とかasio(まだ無いが)とか。 shared_ptrなんぞバイナリー落としてインストールするだけだ。
124 :
デフォルトの名無しさん :2008/01/11(金) 17:24:46
>>123 それを言うならヘッダファイルジャマイカ?
C++相談室どこいった?
落ちた
996レスくらいだっけ? ぎりぎりで落ちたよね。
128 :
デフォルトの名無しさん :2008/01/11(金) 18:31:41
イテレータって何ですか?
>>124 ヘッダもだけどライブラリじゃなくてか?
shared_ptrはもう導入しないでどうするという感じだな 天才が作ってるうえアフォな質問にも丁寧に答えてくれるしな boostの問題はライブラリによってサポートに差があることかな
TR1に入ってるものは全部C++0xで標準に入るんだよな。 shared_ptr weak_ptr bind function mem_fn type_traits...
regex とか random とか tuple とかも入るよ。 んで、auto_ptr は deprecated になる。
>>117 まぁ そうですね。clear()呼べば済む話ですもんね
お騒がせしました。
auto_ptr、deprecatedになるのかw カワイソス strstreamみたいな感じか
破壊的だと使い勝手悪いしなあ。
コンテナに入れられないのがよほど致命的なんだろ。
致命的過ぎるよなー、それ。
139 :
デフォルトの名無しさん :2008/01/11(金) 22:07:12
>>129 いやぁ,shared_ptr だけならヘッダファイルだけ
もってくればつかえるとオモタ.
140 :
デフォルトの名無しさん :2008/01/11(金) 22:08:03
で auto_ptr の直接の代わりは scoped_ptr ?
そんなもん使わずに shared_ptr 使えって事だ。
auto_ptrはreleaseできるのが地味に便利
参照カウンタのオーバーヘッドを気にしてしまう人もいるんじゃないか たぶん
boost::ptr_vectorは地味に便利だ
unique_ptrが楽しみ
参照カウンタ込みで new できるとオーバーヘッドも小さいんだが。 汎用的に作れないもんかね。
>>146 intrusive_ptrではだめなの?
>>147 使うために色々と必要な事があるからなあ。
multimapのいくつかの要素を述語を使って消去したいのですが 何か良い方法はありますか? bool pred(pair<int, int> v) { return v.first == 3 && v.second == 'c'; } int main(int argc, char* argv[]) { multimap<int, char> m; m.insert(make_pair(1,'a')); m.insert(make_pair(2,'b')); m.insert(make_pair(3,'c')); // 消去したい m.insert(make_pair(3,'c')); // 消去したい m.insert(make_pair(3,'d')); m.insert(make_pair(4,'d')); m.erase(???); return 0; } 環境はVC8です。
149です。 bool pred(pair<int, int> v) のところは bool pred(pair<int, char> v) の間違いでした。 お願いします。
イテレータとfor_eachじゃね?
>>151 Effective STL Item9 や JosuttisのSTL本にも載ってるけど
こんな感じだろうか。
bool pred(const pair<int, char>& v)
{
return v.first == 3 && v.second == 'c';
}
for(multimap<int, char>::iterator it = m.begin(); it != m.end(); )
{
if( pred(*it) ) {
m.erase(it++);
}
else {
++it;
}
}
試してはいない。
>>152 begin()とend()じゃなくて、lower_bound()とupper_bound()の方がいいと思う。
154 :
149 :2008/01/13(日) 20:56:22
>>152 お示しの方法でうまくいきました。
>151,152
ありがとうございました。
>>152 折角mapなのに全検索は勿体無くねぇ?
156 :
149 :2008/01/13(日) 21:47:11
>>153 lower_bound()とupper_bound()
にするのは速度的な問題でしょうか?
しかし、キーを二回余分に渡すのもちょっと面倒ですね。
>>152 一旦キーでマッチしたものを、すべてシーケンスコンテナに入れて
そこからさらに絞り込むっていう方法も考えていたんですが
今、私が書いているコードで使う要素数が多くても3個ほどなので
あまり変わらないような気がしました。
要素が多いとまた変わってくるかもしれません。
>>153 >>155 確かに。multimapだった。
equal_range()でイテレータの組を取ってもいいか。
>>156 全部の要素をlinerで舐めるのは非効率だわ。
上の人たちが言ってるやり方が効率が良い。
upper_boundとlower_boundは大小の順にソートシーケンスに 適用するアルゴリズムだ。 std::mapはデフォルトでキー順に既に要素を挿入した時点で ソートされているのでまさに効率の良い方法。 Cで言うとbinary_search()な。
>>156 KeyとValueの両方の条件で削除要素を決定するなら
汎用性を考えた場合、Linerになるけど全部舐める
しかないかもな。まあ、今の場合は削除対象を絞る
条件がKeyが3に固定されてるからいいけど。
>>156 149の通りの条件なら、Key == 3 の範囲をequal_rangeで得て、
その範囲に対して Value == 'c' を消してまわるのが速そう。平均的には、ね。
総要素数に対してequal_rangeの範囲が無視できるだけ小さいならおk。
実際に行いたい条件が149と違う場合は話が違ってくる。
Keyが単一とは限らないとか。...って、
>>159 に書いてあるか。
そういえばmultimapってどういう用途に使ってますか? mapは連想配列の様に便利に使ってますが multimapという道具の使い方がいまいち思い浮かばない…。
162 :
デフォルトの名無しさん :2008/01/14(月) 11:02:35
得点が0〜100点で、名前を要素とする 同一得点は存在するからマルチ
163 :
161 :2008/01/14(月) 11:07:45
>>162 なる。 70点取った人を羅列その他できますね。 サンクスです
STL限定なら別だけど辞書ならbimapの方がよくね?
用途の話しだ
「ようとのはなししだ」ですか?
とりあえず度数分布表以外にも例挙げてよよよ
用途の話だ。
>>162 この例で、0点のダメ男君が何人いるかと、
その名前の列記とかってどうやって出力するの?
mismatch()とか使うのかな。
foreachループでフラグ立てながらは勘弁
俺ならequal_range
割と典型的なequal_rangeの出番だと思う。 人数だけが知りたい場合は、countがいいかな。もちろんメンバ関数のほうね。
175 :
172 :2008/01/15(火) 11:07:03
>>173-174 ありがとうございます。 equal_range、及びcount便利ですね。
説明読んでて、「該当者のいる得点一覧」(無重複の使用キー一覧)の方法に
ぶちあたった。 もうちょい調べてみます。
176 :
デフォルトの名無しさん :2008/01/17(木) 18:02:56
配列の先頭を指すポインタと末尾を指すポインタのペアを返す テンプレート関数を作成したいのですが、うまくいきません。 以下のコードはVC++6.0でもBCC5.5でもコンパイルエラーです。 正しい方法を教えてください。 #include <utility> #include <algorithm> template <class T, int n> std::pair<T*, T*> iseq(T a[n]) { return std::pair<T*, T*>(a, a + n); } int main() { int x[] = {6, 1, 3, 4, 2}; std::sort(iseq(x).first, iseq(x).second); return 0; }
VC6やBCC5といった糞コンパイラを捨てる
>>176 #include <utility>
#include <algorithm>
#include <iostream>
#include <iterator>
template <class T, int n>
std::pair<T*, T*> iseq(T (&a)[n])
{
return std::pair<T*, T*>(a, a + n);
}
int main()
{
int x[] = {6, 1, 3, 4, 2};
std::sort(iseq(x).first, iseq(x).second);
std::copy(x, x + sizeof(x) / sizeof(x[0]), std::ostream_iterator<int>(std::cout, " "));
}
ああそうだわ、
>>178 はBCCじゃコンパイルできないよ。
VC6はどうか知らんが、VC7.1やVC8、VC9なら行けると思う。
gcc3.4.5でもOKだった。
>>179 bcc5.5.1と5.8.2でコンパイルできたよ
BCC5.9.2でも行けるね。
182 :
176 :2008/01/17(木) 18:25:31
>>178 ありがとうございます。
>>180 さんがおっしゃるとおり
bcc5.5.1ではOKでしたが、VC++6.0ではダメでした。
boost::begin()やboost::end()の実装を参考にしてみれば?
>>184 iseq(T (&a)[n])
この部分が解析できないフロントエンドを持つコンパイラ。
VC6 とか無理だった記憶がある。
>>185 T (&a)[n] の仮引数aの型が解らんてこと?
aが配列参照と理解できないってことかな
配列参照に対応していないだけ。
BCCは template で T (&a)[n]とやってあると大丈夫みたいだが int (&a)[n] のように型を決め打ちされてしまうとコンパイルが 通らなかったような。 templateの特殊化には対応してんのかな。どっかいろんな細かい 部分が標準と挙動が異なるのでSTLportから見捨てられかけたり boostへの対応度が低かったりする。
コンパイラ実装者にとってパターンマッチほど面倒くさいものはない。
191 :
デフォルトの名無しさん :2008/01/18(金) 09:13:16
VC6 はもうそろそろ寝かせてやって, VC9 使おうよ… Express Edition もあるんだから.
VC9も色々バグがあってヤヴァイみたいだけどな STLをやboostを使うならVC8がgccとかも含めて一番安定して使えるかも
質問です。 equal_range()でvectorの特定の値を検索したいのですが vectorの要素はマルチキーなのです。 typedef struct{ int x; int y; }DATA; このような感じの場合。 どのようにすればいいのでしょうか? やはり自分で作らないと出来ないのでしょうか? 宜しくお願いします。
194 :
193 :2008/01/18(金) 10:30:48
事故解決しました。 第4引数があるんですね・・・。 でもこの引数、ググっても、日本語のページは、4件しかヒットしないや・・・orz
boost使うなら現状VC8の方がいいだろうが それ以外バグが問題でVC8使った方がいい ってあり得るの?
>>194 STLはそういう使い方しないもん。
structじゃなくて、classにしとけよ。
operator定義できないから、多分比較関数定義出来ないぞ。
検索する値はint型、比較する対象はvector<DATA>のDATAっしょ?
比較関数は定義できても、呼び出し側の引数は等価な型を与えるから無理。
先に比較用のoperator書かないと。
structかclassかの問題だったのか
>>196 別にstructでもoperator()は定義できるでしょ。
今はそれはどうでもよくて、strict weak odering条件を満たす
bool operator(const Data&, const Data&);
を定義して、operator(const Data&, const Data&)で
vector<Data>をソートしておいて、eqaul_rangeに同じ
Comparisonであるoperator(const Data&, const Data&)を
渡せばいいんでないのか?
ということを
>>193 は言ってると思ったんだが。
× bool operator(const Data&, const Data&); ○ bool operator<(const Data&, const Data&);
>>198 operator<を定義してたらComparison(
>>194 の言う第4引数)渡さなくていいんじゃ?
あれ?structでoperator定義出来たんだ。
>>200 クラスのメンバーとして定義するなら、そうだね
>>201 structとclassの違いはデフォルトのアクセスレベルだけでしょ。
203 :
200 :2008/01/18(金) 16:00:31
↓って同一?マングル名とかも含めて。 struct xxx { xxx(); private: int n; }; class xxx { int n; public: xxx(); }
class はテンプレート仮引数の型として使えるが、struct は使えない、という違いもなくはない。
>>205 お、ほんとだ。知らなかった。何か理由あるのかね。
typenameでいいじゃない
テンプレート仮引数のclassとクラス宣言のclassって意味が違うんじゃないの。 仮引数のclassは型名を表すだけで、そこにclass入れようがstruct入れようが組み込み型入れようが構わないんだから。
クラステンプレートを引数にとるときは class しか使えないね。
classを使わずにstructを使うメリットって何? コンストラクタ定義しなくても、メモリサイズ的に変わったりするの?
簡単なデータの塊を表現する時に struct を使ってる。 struct Point3d { double x, y, z; }; とか。
構造を保ったままCとインタフェースできる。
template <template<typename T> class C> //OK template <template<typename T> struct C> //NG
template <template<typename T> typename C> //NG これも書いておかないと片手落ちだ
fwrite()でvector<int> vの中身を一気に書き出したいのですが 効率の良い方法はないのでしょうか? vector<int> v; fwrite(v, sizeof(int), v.size(), fp); のような感じで一気に書き出せれば凄くうれしいのですが これではエラーになります。定義されているoperatorがうまくintのポインタの代わりをしてくれるかと思ったのですが どうやら無理のようです。 これは、一度個数分ループまわしてintに書き出さないとダメなのでしょうか?
&v[0]
あるいは &v.front() 好きな方を使え。 次期 C++ だと v.data() で良くなるみたいだが・・・ まだないものは仕方が無い
>>216 ofstream ofs;
と
copy(v.begin(), v.end(), ostream_iterator<int>(ofs, " "));
とかではダメなんか?
fwriteだからバイナリで書きたいんだろ
>>220 じゃあostreambuf_iterator使えば?
222 :
デフォルトの名無しさん :2008/01/21(月) 06:41:18
コンテナの中が連続して配置されていることが 保障されているのはvector だけ? って,list とかでそんなことできるわけないよな.
vectorはC配列との互換性のためにわざわざそんな保証をしてるわけですから
そのために無駄なコピーが発生しまくり
std::ifstream fin( "in.bat", ios::binary ); std::ofstream fout( "out.bat", ios::binary ); std::copy( std::istreambuf_iterator<char>( fin ), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>( fout ) ); このコードって超おせーんだけど、なんで??
>>225 それだとディスク内のin.datにアクセス→ディスク内のout.datにアクセスを何度も繰り返すから、
in.datのデータを一度数キロバイトのバッファに入れてからまとめてout.datに書き込んで
ディスクへのアクセスを減らした方が早いよ。
環境にもよるけど、一度ディスクにアクセスする間にメモリからデータを十万回程度アクセスできる。
読み込みも書き込みもまとめてディスクへアクセスすればシーク時間も節約できる。
227 :
225 :2008/01/21(月) 13:30:36
>>226 iterator を使うと、fstream へのアクセスが 1 文字ごとに
なっちゃうっていう理解でいいですか?
なんとなく iterator のほうがカッコいいかなって思ったんだけど、
使い物にならんほど遅いので…。
素直に
fstream::read()
fstream::write()
を使えということでFA?
つ streambuf_iterator
>>228 俺には
>>225 のコードがstreambuf_iteratorを使っているように見えるんだが。
吊ってくる…
低レベル(遅延書き出しなど)でのディスク書き出しはOSの機能 だと思われ。書き出すタイミングも。 streambuf_iteratorを使う(内部的にsgetc, sbumpc, sputcを 使ってる)ということはプログラムレベルでのストリームバッファ を直接操作してるわけで、ファイルストリームオブジェクトに対して read、writeを使うと非バッファ操作になるから速くなることは ないと思える。実測次第だな。 OSのチューニングなりドライバこさえるなりするのも一考。
最新のドラフトを見ると string も連続性を保証するようになるっぽい。
234 :
225 :2008/01/21(月) 19:58:24
>>231 う〜ん・・・
boost::timer t;
for( int i=0; i < 10; ++i ) {
ifstream fin( "in.dat", ios::binary );
ofstream fout( "out.dat", ios::binary );
copy (
istreambuf_iterator<char>( fin ),
istreambuf_iterator<char>(),
ostreambuf_iterator<char>( fout )
);
}
cout << "iterator=" << t.elapsed() << endl;
t.restart();
for( int i=0; i < 10; ++i ) {
ifstream fin( "in.dat", ios::binary );
ofstream fout( "out.dat", ios::binary );
while( !fin.eof() ) {
char buf[BUFSIZ];
fin.read( buf, BUFSIZ );
fout.write( buf, BUFSIZ );
}
}
cout << "read_write=" << t.elapsed() << endl;
のコードでやったら、iterator=2.093, read_write=0.438で、5倍ほど差がつきました。
環境は WinXP + VC8 です。
まぁ、どうしても iterator 使いたいわけじゃないので、おとなしくread() と write() 使います。
235 :
デフォルトの名無しさん :2008/01/21(月) 20:54:05
multisetの実装について教えてください。 値の重複を許す二分探索木というのは、どう構成したらいいのかよくわかりません。たとえば、 10 8 12 みたいなところ(10がルートで8と12が左右の子)にもうひとつ10を挿入すると、どういう木になるんでしょうか? red-black treeでなく、単なる二分探索木の話でよいので教えてください。
>>234 やっぱりディスクアクセスが頻発するのか。
streambuf_iteratorはstream_iteratorに比べると速いというだけか。
ただ、そのプログラムのread/writeだと正しくファイルがコピーされなかった。
おそらく、fout << fin.rdbuf(); 一行で正しくコピーできると思う。
by VC++ 2008
>>234 fout.write( buf, BUFSIZ );
がコピーできない原因か。BUFSIZEのゴミまでコピーされてしまう。
flushみたいな名前の
239 :
225 :2008/01/21(月) 22:20:19
おお、ほんとだ。
こんな単純なミスをするとはww
ファイルのサイズがBUFSIZの倍数になってたから
正常に動いてるように見えてたみたい
>>236 書き方は rdbuf() が一番簡単ですね。
さっきのコードで
fout << rdbuf();
と
char buf[BUFSIZ];
fin.read( buf, BUFSIZ );
int n = fin.gcount();
fout.write( buf, n );
でやってみましたが(他の部分は同じ)、
rdbuf=1.375
read_write=0.406
で、速度を気にする場合は read(), write() のほうが早いようです。
簡潔に書きたいときは
rdbuf()
速度が重要な時は
read(), write()
を使う方向でいこうと思います。
>>232 あほうすぎる話だなw
こんなのDBの研究者が聞いたら鼻で笑っちまうぜ。
挙句の果てVBかよw
241 :
デフォルトの名無しさん :2008/01/21(月) 22:29:51
/.J でもさんざん馬鹿にされてる
>>239 そうrdbufだと結構遅かったんだよね。
gcount()があったんだ。それ使ったほうが良いよ。
速いに越したことはない。
thx。色々参考になったよ。
>>240 DBの検索アルゴリズムはよく知らんが、
アルゴリズムを考えるときに言語使用は関係ないだろ。
それに、どうせ使ってるのはOSのAPIだろうから、VBだろうが、Cだろうが、
呼び出す速度は同じじゃね?
「OSの基本機能であるファイル名の検索機能」とやらのアルゴリズムを そっくりそのままDBに応用しようとは考えなかったんだろうか??
245 :
デフォルトの名無しさん :2008/01/21(月) 23:05:24
STLの配列にクラスのポインタを入れて使用したいのですけど、 そのようなことって可能なのでしょうか?
>>245 コピーしたときに問題がおきるからだめ
たとえば、
class my_class;
vector<my_class*> v1;
vector<my_class*> v2 = v1;
だと、v1とv2の指してる先が同じになっちゃう。
ポインタが(というか、newが)使いたいなら、boost::shared_ptr 使って
入れろ。
boost::shared_ptr でググって、使い方がわからんなら
STLコンテナにポインタ入れるのはあきらめろ。
>>245 配列?valarray?
ちなみにコンテナだったら可能だよ。
まあ色々面倒だからスマートポインタ使うか
boostのpointer containerとか。
>>246 ,247
ありがとうございます。
では、早速チャレンジしてみます
つーかコンテナにポインタ入れる必要って本当にあるの? 大抵の事ならポインタ入れずに済ませられると思うんだが。
ヒープに作成したオブジェクトをコンテナで 管理したい場合もあるんじゃないかな。
251 :
デフォルトの名無しさん :2008/01/21(月) 23:35:47
>>235 だれかおながいします・・
とおもったけどスレチガイ?
>>244 >「OSの基本機能であるファイル名の検索機能」とやらのアルゴリズムを
>そっくりそのままDBに応用しようとは考えなかったんだろうか??
Windows Index Search の機能らしいので
アルゴリズム自体はそっくりそのままDBです
本当にありがとうございました
>>245-250 class my_class;
vector<my_class*> v1;
普通に使いまくってますが何がいかんの?
コピーしたときに問題が起きるのは使い方が悪い。
>>235 10
10 12
8
multiset の実装と関係あるかどうか知らんけど。
>>256 の記事にも書いてあるけど、親と同じ値なら左部分木に入れる、とか決めておくだけだな
右じゃないの。
259 :
デフォルトの名無しさん :2008/01/22(火) 01:00:51
>>258 どちらかに統一しておけばいいんじゃないの?
>>257 左に入れるとして、同じ値を見たら、そのノードの直接の子供としてinsertするのか(255案)、
孫以下の遠い子供として、leafの子としてinsertするのか(この例だと8のrightとして)、どっち?
std::multisetの場合。
>>253 newしたオブジェクトを入れるんだったら、
deleteのし忘れ、2重に行ってしまうなどのミスを起こすから
やめとほうがよいというだけのこと。
「気を付ける」なんて言葉は信頼できないので、
やるなら246のいうようにshared_ptrか何か使って、
deleteをコンピュータ任せにするほうがいい。
261 :
257 :2008/01/22(火) 01:22:29
>>259 通常と同じ、leafの子としてinsertする
>>255 は挿入順の関係でたまたま直接の子になっただけだと思う
262 :
デフォルトの名無しさん :2008/01/22(火) 01:28:48
>>261 それだと、同じ値を持つノードがツリー上で離れてしまいますよね。
equal_rangeをどうやって実装するのか想像がつかないのですが、簡単に教えてもらえませんか?
戻ってきたイテレータを++するたびにO(logN)のサーチが入る???
>>262 重複を許そうが許すまいが、二分探索木はそもそもそういうものだろ
隣接した要素が木構造の上では離れた場所に置かれることがある
イテレータをどうやって実装するのが普通かは知らないけど、setとmultisetで事情が変わる訳じゃない
>>263 まったくもってそうでした。。。。
イテレータも、単にin-orderでtraverseすれば要素同士が離れていても問題なく連続して触ってくれますね。
COAP!
266 :
デフォルトの名無しさん :2008/01/25(金) 08:16:31
COAPってナニ?
COAP=Containers of auto_ptr Effective STLぐらい買え
ありがとう
269 :
デフォルトの名無しさん :2008/01/25(金) 15:47:58
struc foo { string name; }; std::vector<foo> v; foo *f = new foo; f->name = "ABC"; v.push_back( *f ); とやったときの、findでのABCの検索の仕方が全然解りません。 教えて下さい。
>>269 std::vector<foo>::iterator it = v.begin();
size_t pos = it->name.find("ABC");
あるいは
size_t pos = v[0].name.find("ABC");
271 :
269 :2008/01/25(金) 16:06:52
コードを端折ってすみません;; foo *f = new foo; f->name = "ABC"; v.push_back( *f ); の部分が何度も繰り返してる場合です。 for ( i = 0; i <100; i ++ ) { foo *f = new foo; f->name = IntToStr( i ); v.push_back( *f ); } とか。。
std::vector<foo>::iterator it; for(it=v.begin(); it != v.end(); it++) { if(0 == it->name.find("ABC")) { //hit } } こうかな? もしvの中に連続して文字列が存在していることを期待してて、 それをまとめてサーチしたいと思っているなら、各stringの中身は 別個に確保されてて繋がってないので無理じゃないかと。
273 :
269 :2008/01/25(金) 16:33:03
なるほど。。なんかfind使う意味なさそうですね。 for ( int i = 0; i < v.size(); i ++ ) { if ( v[i].name == "もげもげ" ) puts( "一致" ); } でもいいわけですね。ありがとうございましt。
algorithmのfind()を使って探したいと言ってるのなら、 fooにoperator==を加えてnameとconst char*を比較できるようにするか、 find_if()に比較関数を渡すかすれば、 vector<foo>::iterator it = find(v.begin(), v.end(), "ABC"); こんな感じにも書ける。 <速度的な違いはほとんど無いと思うけど
もしstring.find()の検索効率を活用したいなら 文字列の格納先は単一のstringにして name.append(文字列); を繰り返してどんどん足していくしかないんじゃ。 で、足すときにnameの何バイト目は何個目の要素か ってなテーブルを同時に作って、findの結果から調べられる ようにしておくとか。
アルゴリズムの改良でSTLが使えないか質問です。 現在、キー文字列を与えると、それに応じた 文字列を返すSTL::mapのようなコードがあります。 ただ、返す文字列が可変です。例えば、キー"気温" を 与えると”今現在”の気温「5゚C」を文字列で返すと いった感じです。 現在このコードは ifとelseの連続で構成されたものと なっておりまして、効率面でも文字列比較を繰り返し 行っており、良いものではありません。 これを実現するのに、できればmapに似た簡単で効率の いい形で改良できないでしょうか?
>>276 すぐに思いつくのは文字列から「文字列を返す関数」へのマップだな
"温度"を与えると「温度を計算する関数」が得られるようにする
>>276 map<string, string(*)(void*)> のような、キー文字列→関数のマップを作ればいいんじゃないかな
279 :
278 :2008/01/25(金) 18:20:31
void*ってなんだろう・・・無視してくださひ。。
>>277-279 早速有難う御座います
なるほど関数ポインタをマップですか。 確かに展望良さそうです。
早速コーディング検討したいと思います。 ありがとうございました!
>>273 今更だが、部分一致ならfind_ifを使う手もある。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
struct foo {
std::string name;
};
struct FooNameIs : public std::binary_function<char *, foo, bool> {
bool operator() (const char * match, const foo & f) const {
return (f.name == match);
}
};
int main() {
std::vector<foo> v;
/* vに色々追加するコード*/
std::vector<foo>::iterator it = std::find_if(v.begin(), v.end(),
std::bind1st(FooNameIs(), "ABC"));
return 0;
}
あと、foo * f = new fooしてv.push_back(*f)してるのは、凄く気になる。
てか
>>274 に書いてあったorz>>find_if
てかstringにsjis入れちゃだめでしょ
どこでSJISと特定したのか興味深い。
SJISだとしても、別に入れるのは問題ないだろ。
findとか使わなきゃね。
std::vectorとstd::basic_stringは分かれている必然性があんましない気がする
vectorのメモリ連続性が保証されなくなるのは嫌なので統合反対。
次期 C++ だと string の連続性が保証されるよ。
んじゃ、char_traitsをvectorに入れると只のコンテナじゃ無くなるので統合反対。
c_str に触れればいいだけなような
>>287 統一してしまうとまずいことがあるよ。
vectorは末尾への要素追加のならし計算時間がO(1)じゃないといけないから、参照カウントによる
copy-on-write最適化ができない。stringにはそういうしばりはないから、COWが可能。まぁ最近
はマルチスレッドの関係でCOWなstringは絶滅危惧種だけど。
他にもあったはずだが、とっさには思いつかない。
findしちゃだめって・・もう馬鹿かと。事実上利用不可だろ
そうは思わない。入れ物として使うなら十分。
c_str 使って外部の検索関数使えばいいだろ。
お前ら努力家だな
wstringのことも時々でいいから思(ry
wstring には SJIS なんて入れられないだろう・・・
wstringでSJISが正しく扱えるのかい。
300 :
デフォルトの名無しさん :2008/01/27(日) 01:27:23
これだからWindowsしか知らない奴は。
stringは実用なんて論外としても、wstringもサロゲートあぼーんなわけで。。 もう文字列終わってるな
そこでUCS-4ですよ。
サロゲートあっても find に影響はないだろ?
wchar_t はその環境で扱える最大サイズの文字コードを入れる事ができるサイズであって UTF-16 だと決まってるわけでもないわけだが。実際4バイトの環境もあるし。 まあ、次期 C++ だと char16_t (UTF-16) や char32_t (UTF-32) が追加されるわけだが。
しかしwstringだと98系はもうだめだな。 クロスプラットフォームじゃないじゃんstl。。
クロス文字エンコーディングじゃないだけ。
>>303 UTF-8でもfindは問題ないからそのレベルでいいんだったらwstringを使う意味がない
>>304 それはビット幅だけじゃなくて中身もUTF-16/UTF-32であることが保証されてるの?
そんなもん中身を入れるコード次第だろ。
>>309 sizeは「か」に半濁点とかまで考慮するとUTF-32でもだめ
で、おまえらどうやってんの? string s = "abc"; // sjis!!。findとかしないで。。 wstring s = _T("abc"); // ウニコード。98とかでビルドしないで。サロゲートやばいかも どっちも地獄だな。CStringの方がましじゃね?
>>309 size は配列サイズが取得できれば十分じゃないか?
size()/length()はstrlenと等価だから。元々文字数を返すことを期待してはダメ。
だからIBMがアレを作ったのさ なんだっけアレ 眠くて思い出せない
316 :
デフォルトの名無しさん :2008/01/27(日) 01:51:44
ICU
集中治療室
>>311 つか、ウニコード捨てればええだけの話しちゃうの?
ウニコード捨ててもそんなにデメリットないような… … …
サロゲートはサブマリン的に最近問題に。。Unicode側は昔っから、 Utf-16はランダムアクセスはできない文字コードですよと言ってきたんだけど なんとなく流されて2バイトで便利みたいに扱われたり、たいていsizeは文字数を 返すとか説明されたり。。もう混乱の極み。 Javaとかはlengthは2バイト単位の長さを返す仕様に変わり、文字数の取得は codePointCountが追加されたりどの言語も苦肉の策を講じてる状態。 stlもなんとかしないといけない状況ではある。
>>320 日本語だけ扱ってる状況でサロゲートペア関係あるっけ
むしろ、stringをタダのコンテナに引きずり落とすくらいの意気込みで。
size が文字数返すなら、イテレータは1文字ずつ拾ってくる必要があるし、 そうなった時その型はどうするんだ? って話になる。 UTF-32 で合成があった場合とか、64ビット値を返すのか?
やっぱ速度の問題もあるし、javaみたいにsizeとcodePointCountの両方用意 しとくしかないんじゃないかなあと
325 :
デフォルトの名無しさん :2008/01/27(日) 02:02:41
gccのwchat_tは32bitだから楽勝
>321 JIS2004と愉快な仲間たち。 >323 final はsizeいくつ、って話だよね。
>>325 サロゲートの文字数は取れない点は同じだけどね
イテレータだけじゃなくて [ ] も文字数に合わせた形にする必要がある。 でも、ランダムアクセスなんて無理じゃん?
world_char_tが定まるまで待ちましょう。
結局ランダムアクセス用の冗長なデータを込みにしたクラスにしないとどうしようもないし、 パフォーマンス上そこまで標準に組み込まれることは無いだろう。 まあ、それ用のクラスを string 系列とは別に作ることは可能だろうが、 SJIS とかはまあ無理だな。
length(L"final")が5と帰ってきてくれたら、なにか嬉しい?
wstringのfind,insert,appendとかはサロゲートも平気そうな気がするけど なんとも微妙。。 文字とか文字数を意識した扱いをしようとしない限りは平気なのかな・・?
文字数を指定しての置換とかはやばそうだな。
非常によく使うデータ構造だから、効率を犠牲にして理想に走れないもどかしさ
findは大丈夫そうだけど、insert/appendは、サロゲートの前半だけ+別の文字、 みたいな不正な文字列を受け付けるべきか、みたいな話はあるよね。
英語圏だとマルチバイトうぜーとかしか思われてないだろうしな。
普通insertする文字とかiteratorもfindの結果のiteratorとかなわけで
問題なくね?
>>333 確かに文字数指定でサロゲート文字の途中とかになってたら文字が切れちゃう
よねぇ
もうこういうのは boost の領分かもしれないな。
がしがし書き換えたいならutf32に変換してから、書き換えて、utf8なりutf16なりに戻すほうが簡単そうだ。
結局、find/appendなどの引数に与える文字が文字の途中などでない、 と文字数指定の関数に文字の途中などの数を指定しない を守ってればサロゲートもおけ、でいいのかな?
まぁあと15年位したら皆UTF-32でのんびりやってるさ
>>341 それを守るためにどれだけのコストが掛かるかって話してるんじゃないのか
>文字数指定の関数に文字の途中などの数を指定しない これを守るのがすげー大変そうだ。
まだSJISが使われてると思います><
SJIS 専用のクラスならまあ作れるだろうな。
俺頭から5文字取るみたいなコードとりかえしがつかないくらい書いてるな
>>341 文字数ならサロゲートを割ってしまうことはないよ。
サロゲートペア一組で一文字だから。
wchar五個分でなくて、5「文字」分きちんと取れるコードを?
たとえば、 「か゛」は1文字という扱いでいいのか? 「か゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛゛(略」 みたいなどうしようもない連中はどうしよう?
>>348 std::string(wstring)の「文字数指定」は、1文字が固定長のコード体系が前提だから、サロゲがあると壊れるよ。
>>350 それペアになってなくない?
>>348 >サロゲートペア一組で一文字
一組で4バイト(結合文字は6バイトもある)
で、文字数(というより2バイト単位)指定はアウト。
s = サロゲート文字列
s2 = s.substring(0, 5)
とかやったらあぼーんでしょ
>>352 文字数というのは、キャラクタ数という意味で使った。
CString的にTCHAR使えてさらにクロスなものはないのかね?
>>350 合成文字は2キャラクタでしょ。
合成文字をぶった切ると、意味は通じなくなるかもしれないが違法ではない。
ああ、その「キャラクタ数」というのは、要するにUTF-32換算なわけか。
Winではstringは使うな。2バイト目が1バイト目とかぶってやがるからな。 wstringはサロゲートに注意して使え。途中で切るなよ。 Win98とかまだやってるカスはCStringでも使ってろ。 LinuxではstringでもEUCとUTF-8は2バイト目が1バイト目とかぶらないからまだ なんとかなるはずだ。 クロスにしたいなら文字列クラスは当然自前だろ? が俺の現状の認識
358 :
デフォルトの名無しさん :2008/01/27(日) 03:02:31
>>357 追加でMac OS XはCFString使っとけ。以上。
>>357 OS 関係なくてエンコーディングの話だろ?
Windows でも UTF-8 使えば問題ないし、 Linux でも Shift_JIS 使えば問題は出る。
クロスにしたければエンコーディングを OS 任せにしなければ良いだけの話。
たとえば UTF-8 を使うと決めれば std::string でもいけるでしょ。
>>361 だけの話・・って、実際にUTF-8でやったことないんだろ?試しにやってみなよ。
APIに渡すとき、コンソルに出すときすべてに変換をかます必要あるだろ?
文字リテラルはどうするんだ?ソース内のUTF-8はまだコンパイラのサポートが微妙だぞ。
現実的じゃないんだよ。OSが正式にサポートしてるSJISとかUTF-16以外を
内部エンコーディングにするのは。
363 :
デフォルトの名無しさん :2008/01/27(日) 05:33:05
1文字が何バイト使うかはどれ使っても一定ではない どれを使うか決まっていればどれ使ってもよい
UTF-32は4バイト固定。でも合成文字があるので結局同じ問題は残る。
365 :
デフォルトの名無しさん :2008/01/27(日) 06:53:55
一方ロシアはモールス符号を使った
合成文字なんて捨てろ すべての文字を表現したいなんて無駄の極み
おいおい、放棄かよ
368 :
デフォルトの名無しさん :2008/01/27(日) 08:37:31
>>362 入出力と多言語以外の問題はなし 日本語使うんだったらどれでも同じ
入出力にコンバートするのに手間がかかるかどうかだけ
全部画像でおk
16x16ピクセル(256ビット)のパターンで全ての文字を表現するとかどっかで見たな。
文字コード総合スレだと思った つーかPDFでおk
( д ) ゚ ゚
>>365 一方ロシアは画像を使った
こっちの方がしっくりくるな。
>>370 宇宙の星にそれぞれ新しい文字で名前つけてもあまるだろw
一文字32バイトは流石に先取りしすぎだな
string path = "c:\\機能仕様書\\01.doc"; path.find("\\"); こんなであぼーんするstringは危険としか言いようがない
そんなアホなことをする方が悪い。
1文字に1GB
もう OCR でいいよ・・・
人間様の認識能力を利用する形が最強
人間なんてよく読み間違うじゃん
>371 CID(AJ15)のことか? あのコードも印刷以外に使うのは 結構アレなんだけどなー。
C++ メンバ関数内で スコープ解決演算子で classname::メンバ変数 の値変更するのと this->メンバ変数 の値変更するのは何が違うの?
struct P{int m;}; struct C : public P{ int m; void f(){ this->m = 0; this->P::m = 1; } }; みたいな話。
>>377 findが使えないstringって・・・カスめ
path[path.find("\\")] == '\\'になるじゃん、ちゃんと。
返答ありがとう。 最初の this->m は C のオブジェクトのメンバ変数m this->P::m は何でしょうか?
>>386 マジレスすると「能」の2バイト目の「\」がfindで見つかっちゃったんです。
string s = SJISの日本語;
はやっちゃだめなんです。初心者はみんなやってしまうんですが。
>>384 >>390 継承したときに変数名かぶった場合コウ書くんですね。
でも、多重に継承した場合、どう書くんだろう?
scope
>>392 間の型へ一旦 this をアップキャストすると良い。
>>391 だから、find とか使わない分には使っていいんだってばよ。
あー、ダイヤモンド継承か。 P1::P2::Pb::a = 100; みたいに、継承順を追いかければ指定できたような・・・
char []hoge = SJIS文字列; とかやって、 strchr( hoge, '\\'); ってまずいじゃん。 でも、「char配列にSJIS文字列入れるの禁止」って言うのはどうよ、みたいな。
別の言語の癖が出てるぜ
文字コードの話って、荒れる割に全然面白くないし、有用な知見も得られないんだよな。
結局毛唐が ASCII 以外どうでもいいと思ってるからな。
何も考えずに動いていたCStringがなつかすぃ。。 そういえばなんでがんばってfind禁止のダウングレードのstd::string使ってるん だったっけ? だれかどこでも動くCString作ってぇぇ
ドザは Windows のことしか考えないから困る。
どこでも動く? どこでもSJIS使うの?
Linuxとかカスいらねーし
Mac では SJIS 使わん事も無い。 UTF-8 や EUC も使うが。
ASCII自体が腐ってるからな。誰だよ、あんなコードにしたのは。
>>405 いや、できればマクロとかでプラットフォームごととか文字コードとか
切り替えられてさ、当たり前だけどfindとかも問題なく動いちゃうやつ。
CStringみたいに楽に使えて、でもUTF-8とか16とかも平気な感じ。
std::ustringみたいに統一しちゃってさ。boostとかかな。
findだけの問題ならすぐ解決するけどな。 ただ、SJISのままだと単純サーチにするしかないので効率は悪い。
>>410 そりゃWinの場合は内部的には_mbsstr呼ぶとかして高速化しる
wstringに自動変換する const char *n_str();と wstring(char*)を付ければ解決するような気になるけど?
Windows なら mbs 系でおkだが、 他の環境だとその手の関数あるんだろうか。
ついでに質問なのですが、TCHARみたいにstringとwstringを切り分けるにはどう すればよいのでしょうか?以下のようにしておく必要があるのでしょうか? 他にもっといい方法があるのでしょうか? #ifdef UNICODE #define tstring string else #define tstring wstring まだ98でもXPでも動かしたいので・・
組み込み型にしてもいい位のデータ構造なのに クロスに作るのが難しいこんな世の中じゃ
>>415 とりあえず #define よりは typedef のほうがいいだろうな。
>>415 なにかわからないがよくないことが起こりそうな悪寒
charとwchar_tも切り替えないと。リテラル使ってるところがあったらそれもマクロで囲まないとね。 …めんどくさいでしょ。
つまり、C++0xのユーザ定義リテラルの登場を待てと
>>419 それは TCHAR と _T として既に用意されているだろう。
>>415 typedef std::basic_string<TCHAR> tstring;
>>362 361のようなことを現実にやれるソフトウェアでは、
多言語対応のため、文字列リテラルの大半はソースコードに含まれないとか、
APIはラッパー層があるから変換も余裕とかそういう次元にいると思う。
実際文字列リテラルをまったく含まないのはたいへんだぞ〜。 メッセージ的なものはともかくfind(":")的なパース類もすべてfind(COLON)とか にして事前にUTF-8で用意しておかなくちゃいけなくなるし、全WinAPIをラップする のはいよいよ無理だろうに。カレントディレクトリ一つ取るのも GetCurDir(string& s){ TCHAR t[PATH_MAX]; ::GetCurrentDirectory(PATH_MAX, t); #ifdef UNICODE Utf-16からUTF-8に変換 #else SJISからUTF-8に変換 } 的にすべてのラップ関数を用意してあげなきゃいけなくなるし。。
> find(":") 他に理由がなければ、ASCII分はそのままソースに書いていいと思った。
そんなわけがないだろ。
A 系使えば大丈夫。
せっかくWinがUTF-16なのに内部エンコーディングをUTF-8にして、API呼ぶたびに UTF-8からUTF-16に変換はちょっとやだなあ。 全てのAPIをラップする開発コストに加えて、実行時の変換コストまでかかるし。。 やっぱWinはUTF-16でいきたいね。
いい加減スレチガイだということに(ry
std::string/wstringは最重要のコンテナだしスレ違いとは思わんが・・ 結局文字コード周りはいまいちなのがわかるだけなんだよなあ。。
話の流れぶった切って申し訳ないが言わせてくれ。 なんか良スレの悪寒。
日本語と中国語の区別ができない腐れた文字コードそれがUnicode 中国が大体元凶だけどな
> 内部エンコーディングをUTF-8にして、 > API呼ぶたびにUTF-8からUTF-16に変換 Dのことかー!
>>431 言語の区別ができない文字コードはUnicodeに限らないんだよ
ユニコードは本格的多国語環境や16ビット固定長を宣伝文句にしていたからねえ。 次々と撤回して期待外れだったよな。
だから、多国語ではなく多文字だったと。
見苦しい
ユニコードって、UNIXの文字コードだったから ユニコードって言うんだよね。
おまいらいい加減スレ違いだぞコノヤロー。
ユニコード表みるとハングルが異様なほど文字数が多い 中国だけじゃないぞ
>>441 ハングルは現在全く使用されない組み合わせも全部作るように
韓国が強く要求したんだと
それでbatangが異常に膨れている。
韓国死ねよ。
>>442 にほんだって「あ゛」とかいれてるじゃん。
ごめん、勘違いだったかも。でも日本人だって「あ゛」いれたいしぃ。 可変長で6バイトでもよくなったんだから、なんでもいれていいと思う。
>>442 欧米人にしたらCJK死ねよなわけだが。
なんでなかよくできんもんかね。
仲の良い隣国つーのは歴史上稀なわけだが。 稀つーかあるのか。
日本だって古代は中国と仲良かったじゃん。 あと、中国と韓国。 どちらも、主従関係だけどw
「仲良かった古代」、って遣唐使廃止まででそ。1000年も前の話だし。
当時は海ってのは命がけで渡るもの凄い大きな壁だったわけで、 隣国っつーよりは、日本とアメリカ・・・は言い過ぎかもしれんが、 そんな感じだったと思うぜ。
♪ ♪ \\ ♪ 僕ら〜はみんな〜 生〜きている〜 ♪.// ♪ ♪ ♪ \\ ♪ 生き〜ているけど チョンは氏ね〜 ♪// ♪ ♪ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧∧ ♪ ♪ ∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*) ♪ (゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧ ♪ ∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)∧ ∧(゚0 ゚*)♪ ─♪──(゚0 ゚*)| U(゚0 ゚*)| U(゚0 ゚*)| U(゚0 ゚*)| U(゚0 ゚*)| U(゚0 ゚*)| U | U.| | | U | || U. | || U. | || U. | || U. | |〜♪ ♪ | | U U. | | U U | | U U | | U U | | U U | | U U ♪ U U U U U U U U U U U U
>>447 電脳創世記っていう本にあったんだが、そもそも「CJKその他ヨーロッパの小国死ねよ」
ってやってる連中はアルファベットしかないコードしか使ってなくて、それを日本人が
「文字コード問題は俺たちが解決して業績上げますからメリケン共は口出ししなくても良いよ^^」
って挑発して今の流れになったんだと思う。
>>453 ゲームがメモリをキツキツに使うからって、数バイト〜数十〜数百バイト単位の
標準ライブラリのメモリ確保までキツキツにしても、あんまり関係ないと思うんだ。
どうせ画像やサウンドデータが1個増えればだけでそこらへんの努力は
吹っ飛ぶもんじゃないの?処理負荷にしてもさ。
>>442 漢字使用国がそれだけは言っちゃいかんだろ
「じゃお前ら文字数が多すぎるから統合ね」と言われても何も言い返せない
むしろ韓国みたいにもっと初期の段階で分離しろと言い張れば分離できたかも
しれないのに日本人おとなしすぎ
文字、文字コード関係はこっちいけよ
英語・日本語・中国語間のソフトやマニュアルの翻訳をやってるけど ほぼ同じ意味の文章なら中国語が一番少ないデータサイズで書ける
そんなの中国語知らん俺でも分かるっちゅーの
utf-8で? アニメの中国語のfansubとか見るとかなが入った日本語と 漢字ばっかりの中国語で文字数そんなに変わらんように見えたけど。 だから画数で言えば中国語は不利。
一文字に線をたくさん詰め込むんだから、字数が少なくならないとおかしい。 ような気もする。
>>455 ゲーム機はメインメモリ領域が結構キツイんでないの
詩とか台詞の翻訳はちょっと特殊じゃないか? ってどこへ行こうとしてるんだこのスレは
標準STLではunicodeをちゃんと扱えるんでしょうか? 処理系依存では(例えばVC++とか)扱えそうですけど。
ちゃんと扱う、の定義次第。 wstring, wchar_t を問題なく扱えればOKなのか?それなら問題ないよ。 ロカール処理やエンコーディング変換のための十分なサポートがあるか?それなりしかない。
>>455 コンテナ(というかアロケータ)のメモリ効率は重要だと思うが。
アラインメントやページ境界にかなり気をつかっているらしい。
演算効率についてはちょっと読みきれていないが...
inline展開とか命令キャッシュ効率とか、分岐予測の弱いプロセッサのこととか、
いろいろ書いてある。
でかいボトルネックは取り除いた上でさらにどうがんばるかって話では。
>>463 "Game platform memory metrics"ってところに主要なゲーム機のspecが書いてある。
EAがやたらマルチプラットフォームでゲームを作れるのは この辺がしっかりしてるからかな まぁ無理だろうけど、一部位公開してほしいな
VC9でライブラリを作ろうとするとえらーがでます。 使えないですか?
主語を書け。
むちゃぶりだな
バージョンは5.1.5です。
わたし にほんご わかりません
ベンチャーキャピタルが図書館の設立に失敗?
STLportじゃないの
マルチスレッドにてqueueを使いたいのですが、 STL等にセマフォを任せることは出来ないでしょうか?
基本的にSTLはスレッドセーフではない。
>>479 いまどきの実装であれば、たいていドキュメントにマルチスレッドについて書かれている。
そういう記述が無いとか、書かれた保証では不十分だとか、広い移植性が必要だとか、
ドキュメントを読むのがメンドイとか言うんなら自分でなんとかするしかない。
std::stringの配列の連続性は保障されてないそうですが、 実際配列が連続じゃない実装をしてる環境ってあるんですか?
配列じゃないよ
484 :
479 :2008/01/31(木) 18:50:24
>>480-481 ありがとうございました。 無い事が分かって安心しました。
必死で作って、既に有ったらかなり凹むのでw(勉強にはなるけど)
WinAPIのCreateSemaphore()かmutexで検討したいと思います。
まあ実際はc_str()の動作を速くするために連続の場合が多いけどな。 しかもヌルターミネータ文字まで入ってたり。
>>482 ない。というか、次期の規格(C++0x)で連続性が保証されるようになる。
N2461) 21.3.1 basic_string general requirements [string.require]
3 The char-like objects in a basic_string object shall be stored contiguously.
That is, for any basic_string object s, the identity &*(s.begin() + n) == &*s.begin() + n
shall hold for all values of n such that 0 <= n < s.size().
std::ropeは標準じゃないけど、初めから切れ切れの文字列を つなぎ合わせる事を想定してるな。
だからstd::ropeにはメンバ関数c_str()がない。
でもSTLportのstd::ropeにはc_str()があったりする。変なの。
標準じゃないのに std を使うのは違和感あるよな。
STLportはSGI-STLに妙なこだわりを持ってるよな。 何か言われてんのかな。
> 基本的にSTLはスレッドセーフではない 例えばどんな場合?
>>492 どんな場合って・・・何するにしてもスレッドセーフを要求する
仕様なんてないはずだけども。
STLportはスレッドセーフだったような
うーん、書いてないとスレッドセーフでないってのも・・ beginthread一回でも呼ぶプロセスではstlは一行も使えないってことに なりそうな。 たぶん皆、同一インスタンスに複数スレッドでアクセスしなければ平気 くらいな解釈で使ってるんだよね
標準にスレッドセーフという概念がないから語っても意味ないだろ
スレッドの概念自体が無い
ちっ、また自己責任かよ。つかえねーな
効率のためにintの幅すら決めない言語に向かって何を言ってるのかね
int幅が実装依存なのはちゃんと作ってれば別に問題ないだろ。
原子力発電所も冷凍餃子もちゃんと作ってれば別に問題無いぞ。
AMD64は自然な長さが64ビットなのにintが32ビットだな
intが64bitな処理系は現存するのか? その場合、32bitを示す型は何だろう?
C言語が設計された時期が古いので64ビットとか考えてなかったんだろ
32bitといったらlongなんじゃないのか
>506 まさか、int 64bitでlong 32bitと言ってる?
ねたにまじ(ry
LP64のほうが素直だねやっぱり。 I16/LP32はDOSで経験があるし(w
もうビット数気にする処理には stdint.h 使えばいいということで。
_int64とかタイプしたくないよヽ(`Д´)ノウワァァァン 4G超えのファイルなんかザラだろうが。
typedef すれば?
typedef _int64 long long ってできねーだろ
え?
long long とか名前長くしてどうするよ。
long long は既にあるべよ。long_long_long とかにしようべ。
long long ago むかーしむかし、あるところに長い長いアゴの男がおりましたとさ
_int64とはVC++くさいが、 VC++ .NET 2003からはlong longも使えるぞ。
中学の英語の授業中誰もが経験するであろうネタだな
>>516 別に知っとるが、_int64 の方が短くて分かりやすくていいじゃン
i8 u8 i16 u16 i32 u32 i64 u64 これでtypedefしとけば字数的にはint未満だ。何かとぶつかりそうだけどな。
そこで名前空間ですよ。
以下(8bitのみ未満)の間違い。
my_primitive_type::u64 なげーよ。
だから、自分のプログラム全体を特定の名前空間内に入れて、 そこで i8 とか定義しとけば何も付けなくて大丈夫。
stdintはC++の標準に入ったんだっけか intN_tな連中。
_tてなんかの略?
529 :
デフォルトの名無しさん :2008/02/01(金) 02:30:24
type
>>527 最新のドラフトに cstdint と stdint.h が載ってた。次の改訂 (C++0x) で入るみたいだね。
C++0xはC99の(ほぼ)上位互換になるんですか それともC99で使えてもC++0xではサポートされない機能もあり?
コンパウンドリテラルとか 配列個数に変数使うとか そういうのは C++0x で無視
restricted ポインタとか色々無視されてる。
534 :
デフォルトの名無しさん :2008/02/01(金) 07:54:32
「配列の要素数に変数」はSTLと相性悪すぎだからな。
コンパイル時に型が決まらない、だっけ?
type* v = new type[n]; ... delete[] v; の糖衣構文にしてくれるだけでいいのに。
stlportsは2008には使えないの?
>>538 STLPort はインストーラ(make)が VS2008 にまだ対応していない。
手動でインストールするなら可能らしい。STLport VS2008 でググレ。俺はまだ試していないので、試したら結果を教えてくれ。
>>538 iostream使うとC2487がいっぱい出るよ
っ _STLP_STATIC_CONST_INIT_BUG
>>537 std::vector で何が不満なのさ?
見た目が汚い
はぁ?
std::vector<double> v(i); と double v[i]; なら下の方が綺麗だろう。 2次元配列とかなるともうキモいったらありゃしない。
エェー
547 :
デフォルトの名無しさん :2008/02/02(土) 04:00:52
valarray使えや
[i] はキモいだろ。どんだけ使い込んでるんだよ。 (i) これは正常。むしろ性情。
少し、頭冷やそうか
(O) < くぱぁ ╋ /\
>>548 FORTRAN か BASIC ばっかつかってるからそうなるんだ。
>>546 は
double v[i][j];
より
std::vector< std::vector<double> > v(i, std::vector<double>(j));
や
std::vector< std::vector<double> > v(i);
std::for_each(v.begin(), v.end(), std::bind2nd(std::mem_fun_ref(&std::vector<double>::resize), j));
の方が美しいと感じるようだ。
どうしても知識をひけらかしたい奴がいるようだ。
馬鹿か? typedefしろよ
あんまりしょうもないtypedefたくさん作らないで欲しいお…
グローバルスコープでないならまだ許せる
typedef vector<int> vector_int; typedef vector<double> vector_double; … こんなのがtypedefs.hに延々ならんでるソースを見せられたときは会社やめようかと思った。 結局1年しか勤めなかったけど・・
まぁ普通意味を考えて命名するよな #define VALUE_100 100 て定義する様なもの
>>557 そのレベルだと好みが分かれそうだなあ
vector<string> string_list
とかはありがちだけど。intとはな。。
vectorなのにlist?
>>561 そういう問題じゃない。
・typedef名に意味付けがない
↓のようなコメントと通じるものがある
a += 100; // aに100を足す
・字数がほとんど変わらず、打鍵数減少につながらない
…ところで、あなたは list<string>をどのようにtypedefするの?
んなマジレスされても。。名前考えんのめんどうだからしないねくらいだが
557に意味がないわけじゃないけどな。 typedefされた型しか使わないというのは、 互換性を重視するときは有利になる。
>>565 具体的にどんな移植性の問題が typedef によって解決されるんでしょうか?
>>565 typedefはそういう用途に使えることは否定しないけど、
vectorもintも標準の一部だから、互換性の点でもtypedef vector<int> vector_int;とする意味は無いんじゃないの。
>>566 typedefが移植性のためにあるようなものなのにな。
なぜなにの子供か?
もしかしてあれか? int のサイズが違う環境では typedef vector<long> vector_int; に置き換えて「すっきり解決」とか、そういう話か?
intのサイズ違いをそのレベルで解決すべきじゃない。
つsize_t/off_t
だからやっぱり vector_int は意味無いだろ >565
std:: を省略できれば打鍵数が結構減る。
打鍵数とかでなく、会社からSTLは一律typedefせよ の命題が
課せられれば、vector_int みたいなものは生まれるし、それでもよいと思うぞ。
だから
>>557 がどうこう言う程の問題ではないと思われるが。
こういうのは出たての若いのによくいる 自分は社内でも皆よりよく分かってる と
思いこんでる井の中の蛙ってこった。
std::foreachとかどうやってtypedefするの?
>>574 そんな命題を甘んじて受けるほど奴隷ではありません。
>>574 その通り、会社の方針なら勤めてる以上は従わざるを得ないのは言うまでもない。
そこで、無能だったり考え方の一致しなかったりする上司の下で働く羽目になった場合に取り得る行動は、
我慢して働きつづけるか、さっさと辞めるかの二者択一で、
>>557 は後者を選んだだけだろ。
別に非難されるようなことではない。
>>576 それで問題が発生したとき責任取って解決できるのなら
それでも良いんじゃね? いざとなったら逃げるのはただの口だけ君。
vector<vector<vector<int> > >みたいなものを書かざるをえない状況なら vector<T>をtypedefすることもあるんじゃないかな?
>>579 会社の命令に背いて問題を起こすなんて選択肢はもとからないよ
常識があれば、「従う」と「去る」の二択しか取れない
そんな当たり前の事言われましても。
>>566 このケースでvector<int>は必要なかったとしても、
list<string>はtypedefしたほうがいい。
とすれば、必要あるなしの境界はどこで切る?
こういう皆が使って判断の微妙な境界線は、
「一律typedef」が安全。
STLって型によらずアルゴリズムを記述できるような抽象化を 目指して作られてるはずなのに、ソースはtypedefだらけ。 それを異常と感じないほうがおかしい。
抽象的な書き方をしない箇所もある。適切にtypedefすることには何の問題もない。
そもそもどういう理由でtypedefしてるの?
587 :
デフォルトの名無しさん :2008/02/02(土) 18:04:36
>>584 抽象化するためにtypedefが必要だったりするし、STLなんかtypedefだらけだけど?
>>581 まぁね。 ドラマのまねっこで「僕はそんなことはできません」なんて
楯突いてその後その人間同士が上手く行くことなんてまぁないからね。
ドラマはご都合主義だから上手くいくけどさw
>>588 自分も会社の一員だけどね。そういうこだわりのない人間が集まってるから駄目な会社になったとも言える。
>>574 仕事ってオブジェクト(?)をもっと理解した方がいいよ。
逆に考えて、君がお客で 奴隷とかいうのが車屋の店員だったとする。
君は赤色の車を注文した。 しかし店員は「いやいまのトレンドは白です。
そこは譲れません」 と言ってるのと大して変わらん。
591 :
590 :2008/02/02(土) 18:21:36
本日の課題 授業単元:コンピュータ理論 課題:本字の流れをvectorとlistを使って表しなさい。但しtypedefは使わないものとする。
販売拒否も車屋の勝手だろ それで商売になるならそれでいいし、ならないなら別のことをするだけだ 意に反して赤い車を売らされることはない。もちろん妥協して赤い車を売ってもいい
typedef厨いる?
まあたいして責められてるわけでもないのに いきなり奴隷なんて言葉を使い出す輩とは あまり議論もしたくないな、おれは。 どこぞのウィルス流してつかまったヤツを想起してしまうよ。
>>587 それは抽象化とはいわん。単なる簡略化。
型の違いを意識の外に放り出してしまえるのが本来の抽象化。
現実はその逆。
個人でやってる分にはいいが、人が動かせない大きな岩(プロジェクト)を 動かすには、全員が力合わせて同じ方向に綱引かないと成功なんか ないよね。 俺は反対に引きたい とか関係ねーよ。 社会の歯車とかTVで憶えた訳分からん言葉に流されるべからず。
>>599 std::binary_functionの中とかでやってるtypedefはどう考えても抽象化のためだろ?
>>600 本心は別だろ?w
マが鬱になる原因はそういうところが始まりなんだよ?
>593 本当は「会社として金を儲けるにはどうすりゃいい」というのに従うべきなんだけどな。 車売って利益上げるのが商売なんだから。 >586 色々。主に抽象化と手抜き。一例として template<template<class>class trail_t> struct Policy { typedef trail_t<Policy<trail_t> > Trail; // (snip) }; template<class policy_t> // Policyの派生型を取り込むことを想定 class S { typedef policy_t Policy; typedef policy_t::Trail Trail; // Trailをバンバン活用 }; といった感じで手が抜ける。
>>601 使ったこと無いから知らん
それにここまでの話の流れじゃはそういうとこじゃないだろ
俺は、木しか見ていない
>>557 より、森も見ている会社の
typedefs.hの方が賢いと思う。
ミス それにここまでの話の流れじゃそういうとこじゃないだろ ↑typedef乱用のところな
608 :
603 :2008/02/02(土) 20:01:43
ごめん。policy_tはPolicyの派生型じゃ無いわな。
>>602 本心は当然別よ。 本来人の考えが一致するなんて奇蹟ぐらいの考えで丁度いいよ。
映画あらしのよるに で上手く分かりやすく描かれてるよ。羊と狼が友情築くアニメ風のやつ。
typedefs.h には元々プロジェクトの成功を見ていた2人の心を分かつ効果もありそうだ。
つうかコンテナをvectorからdequeに変えたくなった時や intじゃなくて複素数入れたくなった時に vector_int じゃカコワルイだろ
おまいらソフトウェアプロジェクトマネジメントの本を読んでみ。「ピープルウェア」とか。 >600を実現するためにどれだけの苦労が必要かがわかる。 あくまでマネージャー視点だけど、プログラマ側からするとマネージャーの資質を 測るのに良いヒントになるよ。 ついでに「デスマーチ」もドゾー。現実は厳しいということを教えてくれる古典的名著。
そんな話はマ板でやれよ
>611 変えない……というのは冗談として。 そんときはリファクタリングじゃね?名前総取っ替えだろうね。
>613 だったら>603にコメント入れろよ。放置されてバカみたいだろ。 他のtypedefの使いかたでも良いよ。
だから vector_int には意味がなくて typedef int Code; typedef std::vector<Code> CodeList; とか typedef std::vector<Code> CodeSequence; とかにしたほうが良いんじゃないのって言うのが良識のあるプログラマの意見じゃないかな
このスレでまともにSTLの話をしているのを見たことがない俺
文字コードの次はtypedefかお
で、赤い車は買えたの?
というか、おまいらTemplate使ってる? Policyは非常に強力なコンセプトだと思うんだがね。 本当はもっと制約の少ないMix-in機能が欲しいけどね。 Policy同士で相互依存があると破綻しがちだから、けっこう設計が面倒。
>619 あぁ、早速それ乗って近くの本屋にEffectiveSTL買いに行く予定だよ
メイヤーズもヴァンデヴォーデも質問したら ちゃんと返事くれるんだな。できる人は違うわ。
>>620 相互依存のあるPolicyなんて思い浮かばないんだけど
具体的にどんなの?
あれってヴァンデヴォーデって読むのか……
>622 基本的にはそんな感じなんだけど、Policyの組替えを想定してるんじゃなくて 単にデカいクラスのモジュール化をするときに使ったりしてる。 本当は包含とかでも何とかなるんだけどねぇ。 委譲関数書かなくて良いのが素敵なんで何となくポリシー使ってる。
>624 もちろんきっちり設計してから組めば相互依存はほとんど無くすことができるんだけど、 トライ&エラーで設計するときはそんなこと言ってられないからね。 ルーズに始めるときは、たいてい相互依存バリバリだったりする………… リファクタリングするときも相互依存した状態を経由するから、そういうときも不便。
orthogonalってやつか
>629 直交に分離するのは理想だけど、神様でもなければ一発でそんなに上手く行くわきゃ無いよな。
std::map<T1, T2>をT2順に整列したものを使いたいんだけど、std::vector<std::pair<T1, T2> >に コピーしてsortする方法だと、std::pair<T1, T2>が大きい時にコストがかかるのでイヤーン。 mapの要素へのポインタをvectorに格納してsortしたいんだけどうまくいかない。 std::vector<const std::pair<T1, T2>*>みたいの。 エロい人サンプルコード書いてくだちい。
const pair<const int, int>* addressof(const pair<const int, int> &obj) { return &obj; } map<int, int> m; m[0] = 3; vector<const pair<const int, int>*> vec; transform(m.begin(), m.end(), back_inserter(vec), addressof); こんな感じ?
ありがd。 でもソートも書いて欲しいよママン
>633 そんな難しくもなさそうな気もするけど、まずはうまくいかなかったコードを書いてみれば?
というか std::sortにbool op( const int *l, const int *r) { return *l<*r;} を渡せば終わる話だからなー
pair だからそれだと足りない。けどまぁその程度ではあるんでどういうところでつまるのかな、という方に興味があったり。
こんなのは?意味違うかもしれんが。 typedef map<int, string> Mymap; struct Mycomp { bool operator()(const pair<const int, string>* p1, const pair<const int, string>* p2) { return p1->second < p2->second; } }; int main() { Mymap m; //いろいろ挿入 vector<pair<const int, string>* > vec; for(Mymap::iterator i = m.begin(); i != m.end(); ++i) { vec.push_back(&(*i)); } sort(vec.begin(), vec.end(), Mycomp()); }
sort_inserterみたいの作れば挿入とソートが一発で。コスト的にはあんまり美味しくないか。
640 :
デフォルトの名無しさん :2008/02/06(水) 00:15:23
>>639 pairのsecondだけでソートってできるんだっけ?
641 :
デフォルトの名無しさん :2008/02/06(水) 00:18:18
あー失礼、compare指定すりゃいいだけだ。
642 :
デフォルトの名無しさん :2008/02/09(土) 11:47:37
vectorで使用したメモリ領域を開放する方法を教えてください。 vector<int> v; v.reserve (100000); ぐらいの領域を使った後 v.clear (); cout << "capacity = " << v.catacity() << "\n"; capacityが100000を返してくるのですが、どうやって領域を開放したらいいのでしょうか? v自体はまだ使うので消したくありません。
vector<int>().swap(v);
644 :
642 :2008/02/09(土) 12:01:01
>>643 できた。ありがとう! お前まじ天才
さしつかえなければ、何をどうやって勉強すればお前みたいになれるのか教えてください。
とりあえず つ"Effective STL"
646 :
642 :2008/02/09(土) 12:08:50
買った。 これを読んで俺も天才になる
天才って言葉の使い方間違ってる
むしろ転載に近いよな。
メイヤーズSTLはジョスティスの内容をパクってるものが多い。
で っていう
その本にじょてぃすすげー参考にしたって書いてあったから じょてぃす買った俺が通りますよ。 じょてぃすは絶版になるべきではなかった。
>>651 原書を読み漁ったおれもいますよ。平易な英語だから無問題。
Vandevoorde も忘れないでね。
>>653 TemplateならあるがSTLの本なんて書いてたっけ?
お前ら日本語でしゃべれ
よし今回だけだぞ
>643 の方法だとstd::stringには効果無いのですが、 stringの場合は明示的にメモリ解放する手段て無いのでしょうか?
658 :
657 :2008/02/11(月) 08:06:11
すみません、VC2005のstd::stringだと、作成した 直後の状態である程度のバッファが確保されてるだけでした。
STLにTStringListみたいなのありましたっけ? やっぱ、 >std::vector <std::string> ですか?
>>659 うん。 TStringList という名前だけ見ると、どちらかといえば std::list<std::string> かと。
有難う。 実は、vectorしか使ったことないのです。listとvectorの違いを知りたいです。
大差ある。
vector ランダムアクセス可能。 メモリが連続している。 list ランダムアクセスできない。 当該要素のerase以外で参照・イテレータが無効化されない。(個人的にはこれが一番重要) 任意位置への挿入・削除が定数時間。 独特な操作(spliceなど)がある。 選択する上で気をつけるのはこんなとこか?
なるほど、どうも有難うございます。 選択って意味では、 vector と list を間違えるより、 vector と map(←これもまだ使ったこと無いw) を間違えたら大変な気がしました。
いや、vector使うつもりでlistつかうよりmap使った方が多分マシだぞ
そもそもコンテナに何を求めているかによる。 連続性が重要ならlistもmapも同じくらい散々な目に遭うし、一応コンパイルが通ればいいだけなら vectorでもmapでも問題ない。
ポインタつなげて線形リンクリスト作らされたことってないの?
>>668 標準ではないがstd::slistってのがある。
>>669 std::listだって線形リンクリストでしょ。双方向であるというだけで。
std::list って単方向じゃなかったけか?
いいえ。
あ、ごめ。双方向だった・・・ よく考えたら reverse_iterator 使えるもんね。
連続性が要らないなら、vectorよりdequeつかっとけって誰かえらいひとが 言ってた気がする
要素数が万単位にならなければlistよりvectorつかっとけって誰かえらいひとが 言ってた気がする
むしろvectorがいらない子だろう
オブジェクトのサイズ/要素数が大きくない場合 listはvectorに比べてアロケーションの多さと断片化が弱点になりそうだよね
680 :
666 :2008/02/15(金) 08:45:44
なるほど、今までvectorのみ使ってましたがmapにトライしてみます。
というより、実はネットで拾ったライブラリがmap使ってて、初期化宣言見ただけで”えっ”と思ってもう理解するの必須。
vectorの連続性って、普通の変数配列みたいにメモリがばっとコピーしても大丈夫なんですよね?
何度も文献とかで確認しましたが、結局怖くて1つ1つイテレーター参照してますが。
ところで、map使うとプライマリキーみたいなのが必須ですよね?
キーがいる場合にはピッタリですが、開発途中でやっぱキーいらね、とかなったら、
とりあえず連番で埋めとけば良いわけですかね。
その時点でvectorかlistに差し替えかな。
>>668 線形リスト勉強しました。その頃C++どころかC初心者だったため、氏にました。
で、STLって何て便利なんだろう(これで使い方さえもう少し簡単であれば)って思ってまつ。
↑ >666 は間違いで、665です。
mapについてそんなふうに思ってる人は始めて見たw データベースみたいな複雑なものじゃなくてただの写像ですよ。 電話帳みたいな何かと何かの対応表だと思えばいい。 パフォーマンスに関してはそれを理解してからでいいと思う。 >vectorの連続性って、普通の変数配列みたいにメモリがばっとコピーしても大丈夫なんですよね? 多分大丈夫だけどやる必要ないならやらないに越したものはない。 >その時点でvectorかlistに差し替えかな。 パフォーマンス以前に用途が違うのでそのとおり。 >で、STLって何て便利なんだろう(これで使い方さえもう少し簡単であれば)って思ってまつ。 便利さを追求した結果こうなったんだろう。 ただしその上で、できるだけ簡単にはなってると思う。
mapなんて連想配列ですよ。awk使いの私が言うんだから間違いありません。 >>vectorの連続性って、普通の変数配列みたいにメモリがばっとコピーしても大丈夫なんですよね? 多分じゃなくて大丈夫だけど、memcpy()などを自分で使うのはお勧めしない。潜在的なバグの原因になりかねない。 APIに渡すなどのように、必要に迫られたときに限定した方がいい。
boostとかにTStringListに近いものがあったりしないでしょうかね?
そんな無駄なものはない
ま、StringListクラス宣言して、中の人にmultimapすれば、自分でメソッド作るだけですか。 車輪の再開発とか言われたら嫌だから、既にあるものをなるべく使いたいです。
コンテナに使われている例えば連想コンテナのデータ構造(平衡二分木)とか に詳しい人いる?
>686 どんなことがやりたいの?
689 :
686 :2008/02/15(金) 10:55:33
どちらかというと、やりたいことがあるのでなくて、移植作業のためにTStringListメソッド実装。 CommaTextの入出力、iniファイルの1行処理のためのValues/Namesプロパティ、IndexOf、ファイル入出力メソッド、要素文字連結 etc..
>>689 組み合わせて使えばできそうな気がする。
boost.lambda
boost.string_algo
boost.tokenizer
ファイル入出力はfstreamとalgorithm使えばよし。
typedef vector<int> vector_int; を typedef deque<int> vector_int; に書き換えただけで、うちのソフトの体感速度が上がったw 処理速度アップ!ってバージョンアップ唄えるお( ^ω^)
>typedef vector<int> vector_int; >typedef deque<int> vector_int; kwsk 何が違うのか教えれ!
vectorに数万とかpush_backして再アロケートが発生しまくったんじゃないかと予想
その2つはメソッドは同じなの?
バッファの連続性が必要なくて、 確保すべきメモリ量が事前によく分からないなら、 vector より deque の方が圧倒的に効率的。
いままでboost::shared_ptrのコンテナにstd::listを使ってたけど std::dequeにしたら速くなるのかな でもスマポのコピーは時間かかりそうだな...
push_back のコストは list より deque の方が平均的には少ないはずだが
mapってシーケンシャルアクセス、かつ、入れた順番に取り出す、もできますか?
もっと詳しく
mapをbeginからendまで参照した場合、 順番は、mapに登録した順番になっててくれますか?
704 :
699 :2008/02/15(金) 14:27:50
>Sort Criterionによる kwsk ググっても出ません。
map<string, int> m; m["foo"] = 0; m["bar"] = 1; と、 map<string, int> m; m["bar"] = 1; m["foo"] = 0; で異なる挙動になるようにしたいって事だろ? 標準のmapではどうやっても不可能だと思う
706 :
699 :2008/02/15(金) 14:35:07
え”〜ショック。 つまり、並び順が保障されるのは、vectorとdequeだけですかぁ。
だってmapはシーケンスコンテナじゃないし
>>704 テンプレートパラメータかオブジェクトととして渡す
ソート基準による。
709 :
699 :2008/02/15(金) 14:47:40
じゃ、mapはやめて、vectorします。 vectorのヘルプ見てると、pos番目の要素をとるには[pos]ではなくて、at(pos)を使えと書いてありますね。 atを使わずに[]を使ってると、dequeに置き換えが出来なくなるわけでしょうか?
operator[]は範囲チェックをしないけどatはする 違いはそれだけ dequeにもoperator[]はあるから、その心配は要らない
ごめん。未だに 「Associative Containerじゃ駄目なんですか。じゃあSequenceにします」 が簡単に出来る場面というのが想像できない
線形探索しても痛くないときとか
>>695 >>709 >>676 のリンク先にも書いてあるけど、vectorとdequeのメンバ関数の違いは
・vectorにだけある……capacity() reserve()
・dequeにだけある……push_front() pop_front()
だけ。
いずれもメモリの連続性に関わるもので、前者が「あらかじめ確保しておく」系(dequeには要らない)、
後者が「先頭要素を出し入れする」系(vectorには高コスト過ぎ)。
714 :
695 :2008/02/15(金) 17:11:30
サンクス。 STLってキモカワイイね。
個人的にはlistがいらない子のようなきがしてます
dequeにはspliceが無いだろ?
listはアロケータさえちゃんと作れば、本当はやれば出来る子
vectorはお金がかかる子。 vector(笑)
vectorとdequeの最大の違いは、stackコンテナでdequeがデフォルト コンテナとして使われてることを見ればわかるね。メモリ構造の違い によってvectorは要素を削除した場合に絶対にメモリを解放しないが dequeはチャンクの集まりだから不要なチャンクは解放されることが多い。 (これはstandardでは求められていないらしいが) また、reallocateの際、vectorは全ての要素を移動する必要があるが dequeは必ずしもそうはならない。同じ要素へのアクセスではvectorの ほうが理論的には高速。dequeはメモリ構造上indirect accessとなるから。 このくらいしか気にしてないけど、結局は要素数と実測で決めることにしてる。
>>706 次期C++ではinsert(iterator, value)の意味が変わって、
同順の要素の間で好きな場所に値を挿入できるようになる。
それまではstd::map<Key, std::deque<T> >でも使うしかないね。
メタプログラミングをゴリゴリやってる奴いないの? STLを専ら使うだけ?
C++/TemplateMetaProgramming専用スレってないの?
ないね。 欲しければ立てれば?
過疎りそうだけどな TMPと言ったって大概はSTL、Boostの範疇だし
r、ノVV^ー八 、^':::::::::::::::::::::::^vィ 、ヽ l / , l..:.::::::::::::::::::::::::::::イ = = |.:::::::::::::::::::::::::::::: | ニ= 724そ -= |:r¬‐--─勹:::::| ニ= な れ =ニ |:} __ 、._ `}f'〉n_ =- ら で -= 、、 l | /, , ,ヘ}´`'`` `´` |ノ:::|.| ヽ ニ .:. も ニ .ヽ ´´, ,ゝ|、 、, l|ヽ:ヽヽ } ´r ヽ` .ヽ げ き 724 ニ. /|{/ :ヽ -=- ./| |.|:::::| | | ´/小ヽ` = て っ な =ニ /:.:.::ヽ、 \二/ :| |.|:::::| | / ニ く. と ら -= ヽ、:.:::::::ヽ、._、 _,ノ/.:::::| | /| = れ.盛 -= ヽ、:::::::::\、__/::.z:::::.:| |' :| ニ る り =ニ | |:::::::::::::::::::::::::::::::::::.|'.:Y′ト、 /, : 上 ヽ、 | |::::::::::::::::::::::::::::::::::::_:::::_::| '゙, .\ / ヽ、 | |:::::::::::::::::::::::::::::::::::.|:::::::|.ト、 \ / / 小 \ r¬|ノ::::::::::::::::::::::::::::::::::::::::::::::::| \
TMPとSTLって全然ちがくね?
どっちかっつーと、非 STL 部分の方が TMP っぽいな。 char_traits とか。
iterator_traits
numeric_limits
std::advanceもTMPっていっていいの?
いいんじゃね?
vectorやdequeってさ、変更せず読み込みだけなら複数スレッドからアクセスしても 大丈夫ですか?
volatileつけとけ
誰も書かないならvolatileいらない
MFCやVCLにある、StringOfChar って無いですか? ある文字を指定個数分返してくれるメソッド。
string s(10, 'A');
thx!
>>741 あやうくfor文で回すところですた。
743 :
デフォルトの名無しさん :2008/02/18(月) 18:28:13
>>731 STLの中でメタプログラミングの要素があるのは
iterator_traitsとiterator_tagを使ったディスパッチくらいかな。
>>743 関数テンプレートのオーバーロードを利用した
ランダムアクセスとその他の振り分けか。
でもほとんど使ったことないなあ。
Vectorで、5番目の要素の次にデータを挿入したいときは、どう書きますか?
直接は使わなくても、advance とかで間接的には使ってる事ない?
747 :
745 :2008/02/18(月) 19:44:02
既存の要素が4の場合と5の場合と、場合分けして、記述する必要があるのでしょうか?
既存の要素が1とかの時どうすんの?
>>745 std::vector なら v.insert(v.begin() + 5, value);
とかかな。要素数が最低5個は存在してないとマズイから。
v.size()で要素数調べる必要はあるか。
>>746 そういう意味では使うこともあるなあ。
本では読んだけど自分で書いたことはないな。
750 :
745 :2008/02/19(火) 08:35:45
>v.begin() + 5 あ、イテレーターって足し算できるんですね。 勉強になりました。
vectorのイテレータはランダムアクセス可能だからな。
752 :
745 :2008/02/19(火) 11:15:48
では、vectorのイテレータだけが、+−演算子定義されてるってことですか? (dequeは無理と)
dequeもランダムアクセスイテレータなので+ - は定義されているよ
754 :
745 :2008/02/19(火) 11:42:15
え”〜、自分vectorのみ使ってるのに、それじゃvectorはやっぱり要らない子じゃん。
+や-ができないのは、たとえばlistとかsetの双方向イテレータ。 こいつらでは、インクリメントやデクリメントを繰り返す必要がある。 そんなときはstd::advanceなんていう関数が既に用意されている、もちろんO(N)。 vectorは、要素のメモリアドレスの連続が保障されているので、 組込の配列やmallocなんかで確保したメモリと同じように使えるという点が決定的にほかと違う。 例えばC用のAPIに渡すバッファなんかにも使える。
756 :
745 :2008/02/19(火) 11:53:08
>vectorは、要素のメモリアドレスの連続が保障されているので、 その通りなんですが、上レス読むと、やっぱふつーはイテレーター使えって逝われてるじゃん。
>>745-750 std::vector<int> v;
if (v.begin() + 5 > v.end()) v.resize(5);
を実行したら、VS2008 では Debug Assertion Failed! で落ちた。
v.end() を越えるような vector::itrator::opearator+() の結果に対して、
_SCL_SECURE_VALIDATE_RANGEマクロが範囲外を検出して例外を起こしている。
言いたいことはわかるが、融通利かせてほしい。
じゃ malloc的な使い方する時は、あえて vector<int>って直書きしないとちょっと恐いな。
>>756 そうだから、vectorで要素へのポインタを使うのはchar*な引数に渡すなんて使い方くらいだね。
すまん、char*に限らず任意のT*でいいんだ。
>>757 組み込み配列だって要素数超える足し算は未定義動作なんだぜ。 assert() が
入ってる分ありがたいぐらいだ。
イテレータについて質問です。 イテレータをインクリメントするコストはコンテナによって違うと思うのですが、 STL解説サイトなどで、そのことについて触れているのをみかけません。 速度を知りたければ、実装毎にテストして計るしかないのでしょうか?
>>762 実際の速度(具体的な処理時間)を知りたいのならそれでいいんじゃね?
ソースやアセンブル結果を見て見当をつけても良いけど。
VC++2005で、 std::map<std::string,int> mp; mp["key000"]=0; とすると、「stringに>演算子がない」ってエラーが出るんだが、これって標準C++準拠の正しいエラーなのかな? それともVC++2005のstringの方がおかしいのかな? ネットで検索した時に普通にstd::stringをキーにしてるソースあったんで、問題ない書き方だとは思うんだが。
>>762 折角ソースがあるんだから読めばいいんじゃね?
>>764 標準準拠である確信は無いけど、g++-4.2.3では普通に使えた
>>764 VS2005でその二行を今書いているコードにペーストしてビルドしたけど、普通に通ったよ。
>>764 エラーメッセージを変に略さずに、そのまま晒したり Google に放り込むと、
なにか余計なことをしているのが見つかるかもしれない。
ヘッダincludeしてない時に出るメッセージに似てる…
>>764 ヘッダのincludeが足りてないのでは?
#include "stdafx.h"
#include <map>
#include <string> ←これをコメントアウトすると、「stringに>演算子がない」ってエラーが出る
int _tmain(int argc, _TCHAR* argv[])
{
std::map<std::string,int> mp;
mp["key000"]=0;
return 0;
}
771 :
764 :2008/02/19(火) 13:45:41
早いレスd。 #include <string>が抜けてただけでした。 お騒がせして申し訳ないです。
772 :
762 :2008/02/19(火) 14:07:09
>>763 ,765
どうもです。
ソース見て見当つけるの難しいですね(if文のコストとポインタ代入のコストの比率がどのぐらいになるのかとかさっぱりです)。
c++の制御文や演算のコストについて、本などでほとんど目にしないのですが、皆さんはどうやって勉強されました?
>>772 環境によって違うんだから、ある程度一般化せざるをえない本なんかで「勉強」するのは
無理だろ。
速度が要るプログラム組むときに、いろんなコードに対応するアセンブリを見て経験的に
身に付けるのがいいんじゃね?
環境が変われば結果が変わるということにも気をつけないといけない。
774 :
762 :2008/02/19(火) 14:47:14
>>773 なるほど。
経験的に身につけていくしかないですか。
速度見積もるのに技術がいる上、環境で変わることを考えると、
速度はあまり気にせず、プロファイリングしてからボトルネックとなっている部分だけ考えるのがいいんでしょうね。
ばかすぎる
自己卑下ですか?
スパコンやx86-64のSSE2最適化の場合はvectorを使って、ベクトル化させたい場所はポインタに変換してる。 iteratorなんか使うと最適化してくれないし。
>>772 まあ、こういう細かい部分を気にするのは悪いことじゃないよね。
でもそれはC++の勉強ではなくて、ターゲット環境のしくみを先に勉強した方が良いよ。
CPUがC++で作ったコードをどう処理するのか、とかさ。
昔みたいにクロック数を数えれば分かるような簡単な時代じゃないけど、
その疑問に答えるためには、結局そのあたりの知識が必要だから。
スパコンでどんなソフト作ってんの?
>>777 やっぱり、本物の数値演算には valarray は使い物になりませんか?
下手にC++で書くよりMatlabで書いた方が早い
>>774 理論的な計算量のオーダーだけは気にしておいた方がいい。
O(N^2)の処理をやっている場所やO(N)の処理を繰り返す場所があったら
適切なコンテナやアルゴリズムを選定することを考えるべき。
結果的にはmapやsetを使うよりvectorを毎回検索、ソートした方が
速いというケースはあるけど、チューニングする以前のエイヤッと決める段階では、
理論的に速いアルゴリズムを選んでおいた方が無難。
>>780 つーか、C++自体が使い物にならなったりする。
ヌパコン屋はFortranしか本気でコンパイラを使ってない。
スパコンは並列化がキモだから、 並列化コンパイラの作りやすい Fortran を作りたがるのかもね。 言語仕様も単純で作りやすいし。
質問です。 vectorのイテレータが有効なイテレータかどうか調べる方法を教えてください。
質問です。 ポインタが有効なポインタかどうか調べる方法を教えてください。 と同じく、ありません。
788 :
785 :2008/02/19(火) 22:30:42
>>787 わかりました。
ありがとうございます。
有効なポインタの全てと等しくならなければ有効・・・かも。 大小比較演算子使えるなら簡単になる。 当然、親となる配列が固定されていないと無理だが。 でも、こういうことしていいのかは微妙。 有効に見えるけど、指してる所が違うとかありうるし。
790 :
786 :2008/02/19(火) 22:40:03
vec.begin() < itr && itr < vec.end() こんな感じでやっていたのですがこれでいいのか不安でした。
やるなら vec.begin() <= itr かと。 それで一応どこか有効な要素は指してるかもしれないが、 「元々指していた箇所から決して動いていない」 ということまでは保証してくれない。
非常に厳密に言えば
>>790 のコードは全く意味がない
そのコードを実行してよい事前条件が、まさに itr が有効なイテレータであることなので
>>790 reallocateされた場合どうすんのよ?
なんだかんだいっても、あれだよあれ。
メジャーリーグに興味持ち始めた頃、STL vs ATLってのがあって何かと思ったら セントルイス・カージナルス対アトランタ・ブレーブスだった。
796 :
デフォルトの名無しさん :2008/02/20(水) 09:16:18
>vectorのイテレータが有効なイテレータかどうか調べる方法を教えてください。 >vec.begin() < itr && itr < vec.end() 自分もこれに関する情報欲しい。 良い記述があれば教えてキボン!
しかしイテレータをそんな長く持ってるのって プログラムを考え直した方がよいような
いや、長く持つんじゃなくて、取得した直後に調べたいんだけど。
*itr で対象をproxyにしてis_valid()でも持たせたら?
そのis_validの実装をどうするかの話をしてるんだろ…
盛り上がってきますたw
>>798 本当に「取得した直後」なら、i != vec.end()でいいのでは。
サンクス
>>802 絶対あってる?保障してくれる?
>>803 どんな手段で取得した直後を想定しているの?
どれだけ力強く保証したって、しょせん名無しのレスだぜ。
こんなに調べる気ゼロな奴だと知ってたら、大嘘教えたのにな。
807 :
803 :2008/02/20(水) 11:14:32
>>806 本人からすると、ここで質問することだって調べる気でしょ。
そういう破壊的なことするのは良くないお( ^ω^)
答になってないぞ。
>>745 に書いてあるのは「取得したあとにやりたいこと」。
質問は「どんな手段で取得した直後を想定しているのか」だ。
810 :
803 :2008/02/20(水) 11:30:31
>>809 ですから、
vector::insertするためにはイテレーターが要りますよね?
で、item[6] としてイテレーターを取得したときに、そのイテレーターは有効なのか無効なのか、という判定。
>>810 イテレータを取得する前に検査すべき。
例えば、std::vector<int> foo(5); std::vector<int>::iterator it = foo + 6;の結果は鼻から悪魔。
>>810 item[6] ではイテレータを取得できないと思うよ
item.begin() + 6 のことか?
itemの6番目の要素が存在するなら、当然有効だし、
存在しないなら、何が返ってこようかくるまいが item.begin() + 6 を実行した時点でアウト
>>810 よくわからんが、こういうことか?
void foo(vector<int>& v, int index) {
vector::iterator iter = v.begin() + index; // この iter は有効か判断したい.
v.insert(iter, 5);
}
ならば、こう書けば良い
void foo1(vector<int>& v, int index) {
if (v.size() < index) v.resize(index); // iterが必ず有効になるように、事前にvectorを拡大する.
vector::iterator iter = v.begin() + index;
v.insert(iter, 5);
}
void foo2(vector<int>& v, int index) {
if (v.size() < index) throw std::invalid_argument("index が大き杉"); // 範囲外なら例外を投げる.
vector::iterator iter = v.begin() + index;
v.insert(iter, 5);
}
作った直後で無効なイテレータってあるのか? 作ること自体が違法だったり、作った後に無効になったりするのなら分かるんだが・
815 :
810 :2008/02/20(水) 12:20:17
>>813 やりたいことは、
ある行の後に1行追加したい、
だから、foo1でできるのはできます。
でも、ある行の後に1行追加するメソッドくらい、std::vectorとかが標準で持ってて欲しいと思うお。
>>815 却下だな。
- 勝手に resize() するなら、途中の要素を何で埋めるか指定しないといけない。
- 挿入位置は iterator で指定するのが標準コンテナの流儀なのに、この場合だけ
インデックスで指定するのはおかしい。
- vector のメンバにしてもユーザーが実装しても効率などは変わらない。
標準で持っていたほうがいい理由が何も思いつかない。
>>814 作った直後のイテレータは、コンテナの中身を指しているか、end()と等値か、だよな。
だからこっちは「本当に作った直後なら、!= vector.end()との比較でいい」って言ってるのに、
この質問者、「自分の訊きたいこと」と「自分の訊いていること」を一致させられないんだよ。
おまえら頑張ってるが、実行効率も考えろ。 結果的に再取得したほうが良かったりして。
819 :
786 :2008/02/20(水) 13:51:57
いろいろ勘違いしていました。 実際はイテレータじゃなくてただのインデックスでした。 0<=index<vec.size() で十分でした。 イテレータの場合は持ってる間vectorを変更しないようにしています。
エエェェェ
これは酷い釣りだ…
結論としてイテレーターは役立たずでOk?
list をイテレータなしでというのはちょっと vector にはいらないけどさ
listの返したイテレータが無効になるタイミングって、 list本体が破棄された場合と、イテレータ先がeraseされた 時だけでしょうか?
元からC++にあった下位概念(ポインタ)が要求するメモリ構造を持っているvectorは、 後から加わった上位概念(イテレータ)を使わずとも、下位概念のやり方で各要素を見ていける、 だから「必須ではない」・・・という意味では、無くてもいいかもね。 実際には、stringやlistがbegin() end()してる中、vectorだけ&vec[0]とか使ってポインタでいじるのは えらく不自然だから、vectorもイテレータで扱ってしまうけれども。
>>825 合ってる(要素を消す関数はerase()以外にもあるけど)。あと標準には
list1.splice(list2);
するとlist2へのイテレータが全部無効になる、と書いてあるけど、
実際にはほぼ間違いなくlist1への有効なイテレータになる。
これは標準の方が訂正される可能性が高い。
>>827 返答ありがとうございます。
listに要素追加したときイテレータを保存しておいて、
それを別なコンテナでインデックス化するってな使い方を
しても大丈夫そうですね。
spliceの
>実際にはほぼ間違いなく
ってところはちと怖いので、使用は避けときます。
>>827 最新のドラフトだと 「移動した要素を指し続ける」 と書いてあるね。
250. splicing invalidates iterators Section: 23.2.3.4 [list.ops] Status: WP Submitter: Brian Parker Date: 2000-07-14 void splice(iterator position, list<T, Allocator>& x); invalidates all iterators and references to list x. This is unnecessary and defeats an important feature of splice. In fact, the SGI STL guarantees that iterators to x remain valid after splice. WPってWorking Paperってなってるけど一度却下されてるんだよね。 で、最新のドラフトだとC++0xで修正されることは決定? WP The proposed resolution has not been accepted as a Technical Corrigendum, but the full WG21 committee has voted to apply the Defect Report's Proposed Resolution to the working paper.
N2461 だと次のように書いてある。 23.2.3.4 list operations void splice(const_iterator position, list<T, Allocator>&& x); 4 Effects: Inserts the contents of x before position and x becomes empty. Pointers and references to the moved elements of x now refer to those same elements but as members of *this. Iterators referring to the moved elements will continue to refer to their elements, ← ここ but they now behave as iterators into *this, not into x.
moveの導入による影響おそるべし
>>831 Working Draftか。
そうなりそうだね。
>>832 list の splice は,標準ライブラリへの move の本格導入以前から,
auto_ptr と並ぶ標準ライブラリにおける move の代名詞だったような?
現行の規格が不必要に制限が強すぎた
(iterator の stability を保証しなかった) だけで,
move 導入とは直接関係ないんじゃないですかね?
>>831 の splice の第2引数が右辺値参照型に変更されたのも
単に一時変数を渡すことができるようにしただけでしょうし.
rvalue reference うぜえな。。 基本仕様としては これが一番インパクトでかいかな。
concept 周りが間に合えばあれも相当インパクト大きいのでは
今まで const Widget operator+(Widget, Widget) とかしてたものが Widget&& operator+(Widget, Widget) になるのか。
テンポラリオブジェクトを渡せるようになるのはいいのだが、 そのせいで左辺値参照でいい状況でもムーブが発生するのが微妙だな。
以下は C++0x を前提にしたレスです.スレ違いですいません.
>>837 Widget の実装と operator+ の機能によりますけれど
値で返すのと参照で返すのでは基本的に意味が違ってしまうのでは?
で, move の恩恵を受けたければ Widget を move 可能にした上で
Widget operator+(Widget, Widget)
となるのが一般的かと思います.
>>838 >そのせいで左辺値参照でいい状況でもムーブが発生するのが微妙だな。
その微妙になる具体例ってどんなのがありますかね?
l1.splice(it, l2); 右辺値参照の場合 1. l2 -> x のムーブ 2. x のノードを l1 に付け替える 左辺値参照の場合 1. l2 のノードを l1 に付け替える
>>839 戻り値をWidgetにしてしまうと代入できてしまうので
constをつけてるんだけど、
@const Widget operator+(const Widget&, const Widget&);
AWidget&& operator+(const Widget&, const Widget&);
現在は@のようにしてるけど、C++0xからはAでいいかなと思った。
どちらも
Widget w1, w2, w3;
if( (w1 = w2) = w3 )
のようなケアレスミスをコンパイルエラーにしてくれると思ったけど、
Aだと (w1 = w2) = w3 はOKになってしまうか。右辺値参照に左辺値
は代入できるか。
const Widget operator+(const Widget&, const Widget&); と書いた場合、const Widget はムーブできるのか?
>839 >838 じゃないけど。 値渡しにした段階でコピーが発生しちゃうから、 Widget&& operator+(Widget&&, Widget&&); Widget&& operator+(Widget&&, const Widget&); Widget&& operator+(const Widget&, Widget&&); Widget operator+(const Widget&, const Widget&); 頑張るんならこうなるんじゃないの? std::string の operator+() はこうなってるが。 あと、微妙ってのは左辺値参照なら単純にアドレス渡すだけで済んだものが、ムーブ処理が発生しちゃうのが嫌ってことなんじゃないかと。 で、↑はそのためにオーバーロードしてるけど。
>>840 引数のl2は右辺値という前提だよね。そうするとmoveの分だけ効率が
悪くなるということかな。
>>842 ん?メイヤーズの本で推奨されてたから従ってる。
>>843 ドラフト見たところでは、例えば
Widget&& operator+(Widget&& lhs, const Widget&& rhs);
の場合、両方の実引数にWidgetの一時オブジェクトを
渡すとlhsとrhsは右辺値になって、両方に左辺値を渡すとlhsとrhsは
左辺値になるという理解でいい?
>>840 現行の list の splice の意味からすると,
splice という名前に前者の操作を overload させると混乱するのでは?
前者は最新の working draft に従えば,例えば
l1.splice(it,decltype(l2)(move_iterator(l2.begin()),move_iterator(l2.end())));
と書けると思いますけれど,これではダメなのですか?
あと,「左辺値参照の場合……」「右辺値参照の場合……」という書き方を
されていますけれど, l2 の型が右辺値参照型か左辺値参照型か,ということですか?
もしそうだとすると,l2 はそのままでは常に左辺値として扱われるので,
void splice(iterator, list<T,A>&);
と
void splice(iterator, list<T,A>&&);
があった場合には, l2 が右辺値参照型か左辺値参照型かに関わらず
常に前者が呼ばれると思います.
しかし void splice iterator, list<T,A>&); は存在しない
>>841 一時オブジェクトに対するメンバ関数呼び出しの overload は
右辺値参照型の *this への拡張が対応するかと思います.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm 例えば,右辺値に対して Widget::operator=(const Widget&) を禁止したければ
class Widget{
Widget& operator=(const Widget&) & { ... }
Widget& operator=(const Widget&) && = delete;
...
}
上記のようになるかと思います.従って Effective C++ にある
>>845 の記述は
C++0x では deprecated になるかと思います.
>>842 move はそのソース (move 元) に対して破壊的操作を行うことになるので
戻り値に対して const を指定しているとその戻り値に対して
move を行うことはできなくなると思います.
Widget& Widget::operator=(const Wideget&); // copy assignment
と
Widget& Widget::operator=(Wideget&&&); // move assignment
があった場合,
>>842 の operator+ の戻り値に対しては
オーバーロードの優先順位を解決した結果, copy assignment が呼ばれるかと.
dequeとvectorの速さ比べをしてみた(gcc 3.4.5 mingw) for(i=0; i < num; i++){ foo += v[i]; } みたいなの。 vectorの先頭をポインタに渡してポインタ経由でアクセス >>>>>>vectorを[]でアクセス>>>vector をiteratorでアクセス=dequeをiteratorでアクセス >>>>>>>(越えられない壁)>>>>>>dequeを[]でアクセス dequeがあればvectorはいらない子みたいなカキコがあったけど、やっぱvectorはやればデキる子だよ。
>>843 ありがとうございます.微妙な具体例が理解できました.
これを気にするならば overload 頑張るしかないですね.
オーバーロードで解決は出来るけど、 沢山あると大変だね。
蛇足ですけれど,
>>843 は書かれているような「微妙な状況」の他に,
引数が一時オブジェクトで,その一時オブジェクトのバッファが
結合後の文字列を保持できる余裕がある場合に,
バッファの再確保を回避できる最適化を積極的に活用できる
というのもあるかと思います.
>>847 元々 splice は move (破壊的コピー) を行うという意味づけであり
右辺値と左辺値を区別する必要はなく,
void splice(iterator, list<T,A>&);
と
void splice(iterator, list<T,A>&&);
をオーバーロードする必要もないと自分は思います
(し,おっしゃるとおり working draft も今のところそうなっています)
>>850 vectorアクセスするのにiterator経由より[]の方が速いって謎すぎる。
何らかの理由で最適化に失敗してるか、assertが効いてるんじゃ?
>>855 ちなみに、倍速くらい
ポインタにすると[]のさらに倍
ちなみにdequeの[]はvectorの[]の4倍遅い
-O2つけて測定コード毎最適化で消してしまえ。
あほすぎ。
ふつーSTLは最適化かけて実測するもんだと思ってたのだが、違うのか?
STL に限らず、実測は最適化かけてからやるのが普通。 最適化しない場合の影響を調べるのでもない限りは。
ふつー、最適化をかけるとvetor::operator[]はポインタアクセスと同じコードに 展開される。実際、gcc3.4.6 -O2ではそう。
dequeのメモリ構造は複数のメモリブロックから成っているので ブロック間でindirect accessが発生するから、要素へのアクセス とiteratorの操作はvectorより遅くなるというのが一般論。
864 :
デフォルトの名無しさん :2008/02/21(木) 00:35:31
>>854 ほほう。結局、
void splice(iterator pos, list<T,A>&& l2);
この場合、l2に右辺値(一時オブジェクト)を渡そうが
左辺値を渡そうが、l2は常に左辺値として扱われるという
ことだよね?この仕様変更のメリットとしては、右辺値も
渡せるということかね。
>>864 splice の定義内では,明示的にキャストをかけるか
std::move を使うかしないと l2 は左辺値として扱われると思います.
>この仕様変更のメリットとしては、右辺値も渡せるということかね。
自分はそう理解していたので
>>834 のように書きました.
右辺値が渡せるので
>>846 に書いたような
l1.splice(it,decltype(l2)(move_iterator(l2.begin()),move_iterator(l2.end())));
みたいなコードも通るようになります.
>>865 後半は漏れの理解不足で分からんけど、アリガトン。
>>866 すいません.
l1.splice(it,list<int>(l2.begin(),l2.end()));
みたいなコードも通るようになるといいたかったんです.
といいますか
>>846 のとかこれの場合は insert で良いですね……orz
>>867 いえいえ。
move_iteratorとか見たことなかったので漏れの理解不足というより
知識不足だった。範囲指定のコンストラクタで一時オブジェクト
をそのまま渡すことができると。
それが、l1.insert(it, l2.begin(), l2.end());で可能だったという
こっですね。
>>813 >vector::iterator iter = v.begin() + index;
やっぱ、イテレーターとるときってbegin()で取るのが正しいのか。
>vector::iterator iter = &v[index];
ってのはダメ?
ってか、おk、だったとしてもvectorとdequeでしか通用しないBADな書き方?
それはポインタ。 全てのSTL実装でコンパイルが通る保証はない。
サンクス。 つまり、書き方という問題じゃなくて、使ってるSTLの実装上たまたまコンパイルエラーが出ないだけなんだね。 すげー賢くなったお( ^ω^)
872 :
871 :2008/02/21(木) 10:30:40
あっ、本当だ。vectorをdequeに変えたらコンパイルエラー。 実行時エラーじゃなくて、コンパイルエラーなのは好感( ^ω^)
散々既出だけど、vectorの場合は、int* p = &v[index];も可能。 ただ、end相当の&v[v.size()]は未定義だから、&v[0] + v.size()を使えって話があった気もする。
いいえ。
>int* p = &v[index]; これはvectorに限らずあらゆるコンテナで可能だろ
そうですね。
え”? dequeでコンパイルエラー出たけど、気のせい? もうテストコード消しちゃったお。
いいえ。
不正確な物言いだったな operator[]を持っていて、value_typeがintであるような、あらゆるコンテナのインスタンスについて可能、と言いたかった
それはうっかりだった、すまん。 vectorのポインタの場合は、配列の要素を指すポインタの如く、 ポインタ演算を使用してそのvectorインスタンスの保持する他の要素も参照できると言えばいいか。
std::stringは、イテレータンを無視して、何文字目かを数字で指定しても、おkだおね?
>ただ、end相当の&v[v.size()]は未定義だから、&v[0] + v.size()を使えって話があった気もする。 で、これは?
&v[0]の時点でただのポインタなんだから、それにどんな値を足しても 指してる先にアクセスしなきゃ大丈夫でしょ。
配列の最後の要素の一つ後の要素のアドレスをポインタ演算に 使用することは規格で認められていた記憶がある。 これが正しければ &v[v.size()] は有効だと思う。
stringのuppercaseはどう書きますか?
>>885 vectorのoperator []は多重定義された関数なのだから、それとは別に規定があるはず。
と思ってX 3014見てみたが、23.1.1 列の中で参照されている表68に
a[n]は*(a.begin() + n)と書かれているがそれ以上は何もない。
もちろん、atはn >= a.size()のときにout_of_rangeを送出と書いてあるけど。
>>885 v[v.size()]の時点で鼻から悪魔確定だろ
>>889 a.begin() + n は dereferenceable ではないので
これを dereference した時点で規格としては undefined behavior,
でよいのでは?
std::string に trim が無いなんて不自由でつね。
まぁ、色々足りないものはある。
>>888 No
アドレス演算子&はオペランドが[ ]演算子の結果の場合、単項&演算子と
[ ]演算子が暗黙に意味する単項*演算子は評価されず、&演算子を削除し
[ ]演算子を+演算子に変更した場合と同じ結果となる。
つまり、&v[v.size()] は v + v.size() に評価されるのであって、
&(*(v + v.size)) とは評価されない。
>>888 C言語もあまり詳しくないだろ?K&Rにも、
>>885 が正しいことは書いてある。
かつ、C++でも同じ。
>>896 それはポインタについてじゃないのか
>>889 も言ってるが、vectorの[]や、vectorのイテレータの+と*は単なる関数かもしれない訳で、
ポインタについての規定がそのままあてはまるとする理由はないだろ
stringの数字チェックはできますか?
>>898 そのとおりだ。ポインタの話しと思ってた。
&v[0] + v.size()でOK
私はヘタレなのでそんなに悩んでる暇があったらイタレータ使っちゃいます ごめんなさい
サイズが0のときの&v[0]は不定だ。VS2005だとアサート。
おかしなコード書きすぎ><
結局STLって無いと困るけど、書き難いね。 複数ファイルイメージみたいなのをバッファに持っておきたいばあいは、 みなさんどうされてます? void*?char*? やっぱ、vector <char*>みたいな感じ?
907 :
906 :2008/02/22(金) 08:54:20
*で宣言しちゃうと、メモリの開放を書かないと逝けないから、 vector <string>の方が良いかなぁ?
908 :
906 :2008/02/22(金) 09:30:49
たまには質問にも応えて欲しいお。
>>906 テキストファイルである保証があるなら兎も角、普通はvector<string>はつかわんだろ。
つーか、ファイルの内容によって違うものを一般化されても困る。
910 :
906 :2008/02/22(金) 10:06:37
テキストファイルじゃなくてバイナリファイルです。 TMemoryStremaみたいなのが欲しいんです。
ファイルをvector<char>に入れるとして、複数ファイルならvector<vector<char> >でいいんでね? なにをやりたいか判ればもっと適当な方法もあるかもしれないけど。
>>906 vector<char> じゃないのか?
913 :
906 :2008/02/22(金) 10:27:17
>vector<vector<char> > おk。 ファイルのロードとか要りますよね。 出来上がったクラスが標準だったり、ネットに転がってて欲しい。
クラス? 何を言ってるんだ? このスレがなんだか判っているか? STLの使い方を提示されたんだから、後は自分で勝手に実装すればいいだろ。
だって普段STL使ってる人たちが、便利な標準クラス使ってるか自作クラスライブラリそろえてるに決まってるじゃん。
もうかまうなよ。
>>913 あのさ、先日からC++BuilderのVCLを移したいみたいだけどさ
STLはVCLと範疇が違うんだから、ファイルロードだのなんだのは
自分でやってくれるかな。
じゃ、せめて、 >vector<vector<char> > をカプセル化した便利なクラスだけでも教えてorz
そんなものないよ
そういえば、copiedはともかくfile_rangeくらいBoostにあってもいいのにって思う。 namespace oven = pstade::oven; std::size_t n; std::vector<std::vector<char> > v; v.reserve(n); for (std::size_t i = 0; i < n; ++i) { std::ifstream is(...); v.push_back(oven::file_range<char>(...) | oven::copied); }
どう見てもifstreamの行は消し忘れです、本当に(ry。
string::compareはありますが、大文字小文字を無視してcompareする場合は、皆さんどうされてるのでしょうか?
stricmp
文字列まわりはSTLに期待すんな、クソだ
そーなんですか。 構造体まわりはSTLで完璧ですが。 で、文字列まわりは何使えば良いですか? ってstringしか無いじゃん。 あー、ハイパーなstringのソース落ちてないかなぁ。
構造体てw
あ、structもclassも等価らしいですが、 何もしないデータの塊にはstruct使ってます。 変ですか?
>stricmp 試してみましたが、やっぱ、.c_str() 付けないとコンパイル通りませんね。 これくらい標準にして欲しいお。
春だなぁ
まだ冬ですよ
これがvipクオリティ
ファイルや文字列処理は微妙にスレ違いな気もするなぁ。
boostでよければboost.string_algoに色々あるしSTLにこだわる必要はないだろ。
boost.string_algoなら
>>922 はboost::algorithm::ilexicographical_compare。
ところでstricmp/strcmpiって標準だっけ?
std::string って、 == で比較できましたっけ?
できる
>>932 stricmpもstrcmpiもstrcasecmpも標準Cには存在しない。
最近のPOSIXにはstrcasecmpがあるけど、locale依存なので
画面に表示する文字列をソートするくらいしか使い道がない。
一瞬、初心者歓迎スレきたのかと思ったぜw
似たようなもんかもw
string って STL に含まれるの?
ど っ ち で も い い 強いて言うならC++標準。 つまんないことにこだわらんでも良いよ。
頻出ネタの上に面白くない議論にしかならないのでスルー
942 :
デフォルトの名無しさん :2008/02/24(日) 11:20:20
std::map<int, std::string> string_map; assert(string_map[1].empry()); assert(string_map[100].empry()); assert(string_map.size() == 2); つまり、存在しないキーを operator[] で指定すると そのキーが自動的に挿入されて値はデフォルトコンストラクタ で作成されてしまうということですか? うむむ、例外になってくれればいいのだが。 std::vector でも operator[] は例外を出さないから それに対応した動作ということなんでしょうか?
単に string_map[1] = "foo"; ってやったときに存在しないキーを指定すると自動的に追加されてほしいからじゃね?
そうそう 存在するかどうかも含めて問い合わせるにはfindを使う
>>942 次の規格の改訂では、存在しないキーに対して例外を投げる at() が追加されるよ。
統一性のある素晴らしい改訂ですな。
947 :
デフォルトの名無しさん :2008/02/24(日) 14:42:27
まぁ copy_if の一軒もあるしな
948 :
デフォルトの名無しさん :2008/02/24(日) 14:42:47
for_each_if とかもほしい
なんで標準にcopy_ifがないんだって話?
vector に data が追加されたり、 何で無かったんだ? って機能が色々追加されてるみたいだね。
そういえば規格の改訂で copy_if() が追加されないのはなぜなんだぜ?
最新ドラフト(これ、最終ドラフトだっけ?)にも載ってないな。
今公開されてる最新は n2521.pdf のはず。無いな。
禿が10年越しの天丼ねらってる、とか?
955 :
デフォルトの名無しさん :2008/02/24(日) 14:59:55
質問失礼します。。 struct ST{ int n; }; vector<ST> v; set<ST> s; int main(){ ST x={0}; v.push_back(x); vector<ST>::iterator itv=v.begin(); itv->n++; s.insert(x); set<ST>::iterator its=s.begin(); its->n++; } のようにすると、its->n++;の行で error: increment of data-member ‘ST::n’ in read-only structure と出るのですがvectorで出来てsetで出来ないのはなぜでしょうか?
今すぐsetのイテレータタグを調べるんだ
ごめんnの方だったのね
>>955 set は常にソートされた並びを保っている必要があるから。
959 :
955 :2008/02/24(日) 15:17:04
>>956-958 さん
iterator経由で勝手に中身を変えられたら困るということは、
setとmapだけの例外扱いなのですか?
イテレータタグというのは初見なのでちょっと調べてみます。
map は second の方は変えれる。
>>959 map の場合は value_type である pair の first がソートキーなので、これは
書き換えられないように const が付いてる。 second は順序に関係ないので
書き換えてもいい。
962 :
955 :2008/02/24(日) 15:31:13
>>960 ,961さん
なるほど、そうなっているのですね。
よく分かりました、どうもありがとうございました。
compareが感知しないメンバなら、mutable付けていじることはできるけどね。
まぁそれは奥の手ということでw
ファイルに簡単に新規作成、追記ができる方法ありますか? ofstreamって、bad()とかfail()とか使いにくい。
ofstream.exceptions(badbit | failbit); ってやっとけばいちいちチェックしなくても例外吐いてくれると思う それが使いやすいかどうかはわからんが…
967 :
965 :2008/02/25(月) 14:25:43
968 :
デフォルトの名無しさん :2008/02/25(月) 16:54:00
そんな機能があったとは
そういえばostreamのfail()が真になる事ってあるの?
>>920 >file_range
ずっと見てても分からないんですが、file_rangeって何ですか?
ファイルの先頭から末尾の一つ後ろまでを指すイテレータのペアみたいなもん
使い方キボン
複数のファイルがあって、それがローデータだったり、テーブルデータだったりします。 複数のファイルを混在させずに簡単にロードしてしまうクラスが欲しいのですが、どんな実装になりますか?
さんks
>>974 boostなんですね。STLに昇格するまで待ってようかなぁ。
ちょっと気後れしてしまうorz
973もヨロ!
>>973 ローデータ、テーブルデータ、ファイルを混在、簡単に、ロード
これだけ曖昧な言葉を並んでるとさすがに意味がわからん。
いや、だからメモリにロードしたいけど、 ファイルの種類が増えるたび書き換えするのは面倒なので、 ポケットみたいにどんどんファイル(ファイル名)を入れていくとその中でメモリになってる、みたいな。
>>978 // ちょっとエスパーにチャレンジしてみたい気分になった
// こうですか?
#include <vector>
#include <map>
#include <string>
#include <istream>
#include <iterator>
#include <fstream>
#include <cstddef>
#include <exception>
#include <iostream>
typedef std::vector<char> memory_type;
class pocket {
std::map<std::string, memory_type> naka;
public:
void ireru(std::string const& filename) {
std::ifstream file(filename.c_str());
file.exceptions(std::ios::badbit | std::ios::failbit);
naka[filename].assign(std::istreambuf_iterator<char>(file)
, std::istreambuf_iterator<char>());
}
};
int main(int argc, char* argv[]) {
try {
pocket pocket;
for (int i = 1; i < argc; ++i) { pocket.ireru(argv[i]); }
return EXIT_SUCCESS;
}
catch (std::exception const& e) { std::cerr << e.what() << std::endl; return EXIT_FAILURE; }
}
乞食は消えろ
さて埋めるか。
982 :
978 :2008/02/26(火) 12:58:13
サンks
>>979 そのまま使ってみます。
でも、ireruメソッドはメソッド名変えるけど。
class pocketもclass memoryPocketの方が良いかなぁ?
978がアホすぎて吹いた
吹いても良いから、自分はどーゆーふーに作ってるか書けお。
スレタイに「初心者」か「宿題」が付いてるスレへ行ってくれ。 マジで邪魔。
>985 おま、ふよー
次スレマダー?
邪魔っていうか、ゴミだよね。 なんでこのスレ見てるんだろう。
リアルで同じ事言われてここに辿り着いたんだろう
ジエンオツ
ということにしておこうか:-)
あれ?あ、そういうこと・・・
STLスレはいらんという事?
まぁ毎度のことだな。 こっちが二ヶ月で 1000 。 あっちが一月半で 800 。 あわせると、だいたい一月でちょうど 1000 か。
新スレからの誤爆とは珍しい。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。