【C++】STL(Standard Template Library)相談室 5
>>1 乙。C++は規模が大きすぎるから、スレ一つではさすがに無理があるよね。
テンプレも長くなりすぎるだろうし。
立ったものは仕方が無い……。
予言
また
>>980 くらいになってから「次スレイラネ」と執拗に主張する人物が現れる
正直、統合でもなんでも良いんだが、例の人の傲慢さが鼻につくというそれだけで スレ立て乙と言いたいw
yata--------------------------------!!!! washo---------------------------------i
俺はSTLスレがあるべきかどうか基本的にはどっちでもよいと思っている。 ただ存在させるのならSTLに限らずライブラリ総合にでもすべきだとは思うが。 けれど、STLスレが立つのは嫌。 いつも前スレが1000まで行った後か直前に新スレが立つから。 もうSTLスレは立たないなと思って安心した頃に立つ。 これは勘弁してほしい。 立てるならもっと余裕を持って次スレを立ててくれ、歴代の1たちよ。
じゃあ900くらいから始めさせてもらうよ
>>9 人格批判されてもね
論を反駁してちょうだい
と言って自分の人格を全く省みない彼であった
人格は出来ちゃったもんはしょうがないと思うけどなー
スレは出来ちゃったもんはしょうがないと思うけどなー
俺が神なのはしょうがないと思うけどなー
20 :
デフォルトの名無しさん :2006/03/31(金) 12:10:39
神木きゅんのチンポしゃぶりたいのはしょうがないと思うけどなー
このスレはたかがSTLごときに懸命で本当にレベル低いですね 我々中華人民は呆れてます では、ありがとうございました
22 :
デフォルトの名無しさん :2006/03/32(土) 01:10:33
流石小日本とは格が違いますね。 ではODAを打ち切りましょう。
ま、中華に勝つには内戦を起こさせるだけでよいンだから、簡単なもんだ。 日本もチェチェンに援助しはじめたしな。
軍部が暴走して日本に核ミサイル打ち込むらしいよ
>>21 > の き
> 々 す
> は、 した
続きは!早く! 詳しく!
>>24 軍部暴走したら内陸にも飛んでく、軍閥でしょ
共産党の私軍だからな。 100年前の袁世凱みたいなもんだろ。
中国が日本を併合する計画立ててるらしい
今回、金出すのを延期したからな。このさい潰してしまえという奴らがいて、内部でもめてるのは事実らしい。 中国に併合なんてごめんこうむる。
ひさしぶりにきたら変なの沸いてるな
firefox.exe notepad.exe みたいな実行ファイル名が記述してあるテキストファイルの中身をlistに格納してから表示するコードなんだけど、 notepad.exeが2回続けて表示されるだけでfirefox.exeが表示されない コンパイルエラーや参照エラーは出てません 以下コード ---------------------------- /*ファイルオープン略*/ char buf[50]; while(fscanf(pFile,"%s\n",buf) > 0) ProcessList.push_back(buf); /*ファイルクローズ略*/ list<char*>::iterator i = ProcessList.begin(); list<char*>::iterator end = ProcessList.end(); while(i != end) cout<<*(i++)<<endl; ---------------------------- どこが悪いのでしょう?
list<char*>をlist<string>に変えるだけで桶 (#include <string>を忘れずに)
>>33 ありがとう
ずっとchar*使ってたけどC++ではString使った方がよさそうだなぁ・・・
場当たり的に string を使って解決したと思いこんでいてもこれから先躓きまくるぞ 一度躓いたらちゃんとその原因を調べてどうして思い通りに動かないのか考えなきゃ ポインタが致命的にわかってない予感なのでとにかく勉強汁
>>32 --
list<char*>::iterator i = ProcessList.begin();
list<char*>::iterator end = ProcessList.end();
while(i != end)
cout<<*(i++)<<endl;
--
C++では次のように書くのが一般的。
・ループ制御変数はループ内でしか使わないならループ内に埋め込むべき。
・インクリメント演算子は後置よりも前置を使うべき。
・イテレータは有効期限に要注意。
--
for (list<string>::const_iterator i = ProcessList.begin(); i != ProcessList.end(); ++i) {
cout << * i; << endl;
}
--
もし型が長いと思うのならば、typedefを使うといい。
ぶっちゃけ、for_eachが使えるならその方が更にいい。
--
static void printString(const string & str) {cout << str << end;}
for_each(ProcessList.begin(), ProcessList.end(), printString);
--
>>36 >・インクリメント演算子は後置よりも前置を使うべき。
そのような “べき” などありません。
イテレータの実装が単純なポインタでないとき、実行効率が落ちるだけです。
イテレータの実装が単純なポインタでないとき、実行効率が落ちるから インクリメント演算子は後置よりも前置を使うべき。
>>34 char* が問題なのではなくて、全ての char * が buf[50] を指しているのが問題。
つまり「++C言語」にすべきだったと
>>41 いや、Cの一時オブジェクトを作っているので間違いではないと思う。
ついでに言えば、代入してしまうとただのコピーになってしまうわけだし。
43 :
デフォルトの名無しさん :2006/04/05(水) 18:37:27
こんな風にしてファンクタを作ります。 単に合計を取るだけです。 template <class T> class Sum { T result; public: Sum(T i=0) : result(i) {} //初期設定 void operator()(T x){result += x;}//合計を取得 T result() const {return result;}//合計を返す }; このファンクタを使うには次のようにします。 Sum<double> s; s = for_each(ld.begin(), ld.end(), s); なんで s = for_each(略) の様に代入する必要があるんでしょうか? for_each はファンクタのインスタンス s の operator() を 順次呼び出してくれるのではないですか?
for_eachの引数は値渡しだから。以上。 あと、無駄なファンクタ作る暇があるのなら #include<numeric>のstd::accumulate使え
すみませんSTLで皆さんは何を使ってますか? VC++版 SGI版 Dinkumware版 STLport版 などですか?
g++版かな?
俺はコンパイラが提供するやつをそのまま使ってる。 コンパイラがSTLを提供してないときはSTLportを使う。
vc++のstlってバグもちってホントですか?
mapのイテレータの動作がほにゃってごにょったことはあるが STLportに代えてからはなにも問題ない
>>48 VC++ 6付属のものはライセンスの関係でバグ修正もできなかったらしい。
.NET 2003のは直ってるの?
組み込みではSTL使っちゃだめなの?
>>52 メモリが増えるから使っちゃ駄目って書いてあったよ、
>>1 のサイトに
>>57 大丈夫、脳細胞は減ることはあっても増えることはない。
角さんのページはリンク切れですか?
>>62 VC7.1か?ライブラリをマルチスレッドに汁。
VC8.0からはマルチスレッドだけになったのでこのようなエラーは出ないはず。
>>63 ありがとうございます、できました。
なんで、こうなるのか仕組みさえ分かってないので、ありがとうございます
>>64 いや(;´Д`)STLportのドキュメント読んでないな?
まあいいけど。
英語はだるいから、暇なときと最後の手段と決めておりますんで
気が付いたら1週間ログインしてなかった
68 :
デフォルトの名無しさん :2006/04/26(水) 01:21:24
MFCスレとどちらにPOSTするか迷ったけど、こっちにします(スレ違いかな?) class CMyButton : public CButton { // ごにょごにょ }; class CMyClient { vector<CMyButton> m_myList; }; で、コピーコンストラクタが無いとかとコンパイルで蹴られます。 CWnd 系って コンテナ化できないんでしょうか? それから、使いたくない CList<CMyButton, CMyButton> m_myList; でも、蹴られます。 何かCWnd系をコンテナにする手段ってあります?
ポインタ使うとか
ちょw vectorの要素をオブジェクトにすると代入毎にコピーコストが発生するお ウィンドウオブジェクトが破棄された前に使われないならポインタ、 ポインタが無効になるかもしれないならウィンドウハンドルを持って CWnd::FromHandlePermanent()あたりを使う手もあるお
CWnd系はコピーが出来ない。 vector<boost::shared_ptr<CMyButton> > m_myList;
VC8で下のみたいに書くと、Cロケールの時はファイルが開けなくて japaneseロケールの時はcoutが動かなくなるんですけども これって正しい挙動ですか? void test() { std::cout << "日本語は表示できる?" << std::endl; std::ifstream ifs("日本語.txt"); printf("%d\n", ifs.is_open() ); } int main() { std::locale::global( std::locale("C") ); test(); std::locale::global( std::locale("japanese") ); test(); return 0; } でもprintf()はどっちでも動作するんですよね いちいちロケール切り替えないといかんのか
74 :
デフォルトの名無しさん :2006/04/27(木) 22:15:37
<algorithm> には make_heap, push_heap, pop_heap があるんですが、 これらは全体に対して作用する関数ですよね。 「ある要素の価値だけが上がった/下がったから、そこだけ再構成したい」 という場合はどうすればいいのでしょう。この操作は全体再構成よりも ちょっとだけ安く済むはずなのですが。 g++ の <algorithm> を見ると __push_heap がそれをやっているようですが、 実装に依存しない(しにくい)標準的なやり方はあるのでしょうか。
>>74 アルゴリズムに頼るのではなく、コンテナを選べば?
set/mapなら自動ソートが働くだろ。
>>75 価値が外部で与えられている場合に駄目だと思うのですが。例えば
int value[10] = {9,8,7,6,5,4,3,2,1,0};
struct comp {
bool operator()(int i, int j) const {
return value[i] < value[j]; } };
としておいて、
set<int,comp> S; for (int i = 0; i <= 9; ++i) S.insert(i);
// なにか処理
value[2] = 100; // 価値が変わる
// なにか処理
としても、価値変更に S が追従しないので、用件を満たしません。これに対して
vector<int> H; for (int i = 0; i <= 9; ++i) H.push_back(i);
make_heap(H.begin(), H.end(), comp()); // ヒープ構築
// なにか処理
value[2] = 100; // 価値が変わる
make_heap(H.begin(), H.end(), comp()); // ヒープ再構築
// なにか処理
と、ヒープを使って陽に再構築してやれば動くのですが、
価値が変わったのが一箇所ならヒープはその部分だけの構築ですむはずなので、
全体を再構築しないですむ方法が知りたいのです。
>>76 > 価値が変わったのが一箇所ならヒープはその部分だけの構築ですむはずなので、
そう思う根拠を基にしたコードを自分で書けばいいんじゃないか?
少なくとも標準では「ヒープ」の実装方法までは決まっていないようなので、
特定の実装方法に基づくのであれば、自分でコードを書くことになりそう。
>>76 そりゃあコンテナというかデータの扱い方が根本的に間違ってるわ。
どうしてソート済みコンテナと、そうでないデータ列を同列に考える?
取り替える(erase してすぐ insert する)という操作があればいいのか。
>>77 自分で書けばよいというのは本当にそのとおりなのですが、
せっかく STL というものがあるので、使えるなら使いたかったのです。
特に push/pop だけを許すなら priority_queue で十分なのに、
わざわざ内部実装のヒープ操作の関数を公開しているのだから、
何かその手の方法があるのでは、と思ったのですが。
>>78 目的が「価値が変化する要素の集合に対し効率よく最小の要素を取り出す」
ことなので、極端に言えばこれさえ実現できればコンテナなんてどうでもいいのです。
set を持ち出したのは 75 で set はどうかと提案されたためです。
>>79 残念ながら普通のヒープの実装では delete_heap -> push_heap の比較回数は
make_heap と同じになるので、その操作ではうれしくありません。
>>79 76 のような外部から順序付けを変更されてしまうような比較関数は
set や map の引数として要求される strict weak ordering にならないので、
どうやっても無理。
アルゴリズムスレ逝け。スレ違いだわあんた。
>>80 ヒープ操作が公開されてるのは、任意のランダムアクセスシーケンスを
その場で priority queue として使えるようにする make_heap() と、
最大計算量 O(N*logN) の sort_heap() のためと思われる。
>>82 「〜というアルゴリズムは STL 使ってうまくかけますか?」って話だろ。
そんなのアルゴリズムスレなんかに持っていかれても困る。
> 「価値が変化する要素の集合に対し効率よく最小の要素を取り出す」 これはアルゴリズムスレ行きだな。
86 :
72 :2006/04/28(金) 11:29:06
>>73 cout.imbue( locale("C") )
とかやっても globalがjapaneseの時は表示できないんです
fstreamも、imbueしてもglobalがCの時はファイル開けないし・・・
だいたいlocale::globalに指定したのって、指定された後に
生成したオブジェクトにのみ作用するんですよね?
それでcoutの挙動がかわるのは問題ないんでしょうかね
>>86 は?なんでせっかく作った japanese ロケールを imbue() しないの?
88 :
72 :2006/04/28(金) 16:25:06
>>87 わかりにくかったようですいません
globalに"japanese"ロケールをすると、coutが日本語を「処理しなく」なるんです
globalが"C"ロケールだと、coutは日本語を吐いてくれるんです
cout.imbue()については、"C"でも"japanese"でも日本語を処理してくれました
どうも関係ないようです
で、困ったことに fstream は globalが"japanese"ロケールじゃないと
日本語名のファイルを開いてくれないんです
これだと、日本語名のファイルをひらいて標準出力に日本語を吐こうとすると
そのたびに globalロケールを切り替える羽目になるんじゃないかと・・・
# もしかしてうちだけ・・・?
89 :
72 :2006/04/28(金) 16:28:19
>>88 に追記です
globalに"japanese"ロケールを指定してから、cout.imbue()で
"C"、"japanese"ロケールの両方を試してみましたが
どちらも日本語を処理してくれませんでした
>>83 うーん、そうですか。
しゃーないので、自分で書くことにします。ありがとうございました。
>>90 ヒントとしての iterator 付きのinsert がそういう用途なんじゃない?
ちゃんと実装されてるのか、ただのinsertと同じなのかは実装依存だろうけど。
>>76 の例だと、
// なにか処理
// 価値が変わる。
// 一旦erase
iterator it = S.find(2);
it = s.erase(it)
// 価値を変えて
value[2] = 100;
// ヒント付きで再度insert
s.insert(it, 2);
7 から 100 は極端な変化だけど、大きいほうだというのは共通なので多少は
効率化されるかもしれない。
>>91 まず
>>81 。
ソート済みリストや配列を使って同様な実装すればいいんだけどね。
list を使って「一旦 erase 」や「再度 insert 」の部分を
退避用 list との splice で置き換えればなかなか効率的なものができそうだ。
>>91 各要素を指すイテレータがどこにいるかを覚えて find の手間を無くすと、
set が B 木の仲間であり、insert がうまく働けば、ヒープの部分再構成の
最悪比較回数とほぼ一致するみたいですね。
ちと書いてみてパフォーマンス計ってみます。ありがとうございます。
94 :
デフォルトの名無しさん :2006/04/30(日) 13:41:22
先生、質問があります。(・д・)ノ 自作のOutputIteratorカテゴリのイテレータがあるとします。 コピーコンストラクタまたは代入でコピーして 一方をインクリメントしたときに もう一方もインクリメントされてしまう実装 (内部でboost::shared_ptr持ってるなど)は OutputIteratorカテゴリに違反しますか? (例) A::iterator st1 = a.begin(); A::iterator st2 = st1; cout << *st1; // "1"と出力 cout << *st2; // "1"と出力 st1++; // cout << *st1; // "2"と出力 cout << *st2; // "2"と出力 st2++; // cout << *st1; // "3"と出力 cout << *st2; // "3"と出力
>>94 別に違反しない(OutputIteratorを二つ引数に取るアルゴリズムは
存在しない)が、あまりお勧めはしない。
>>95 >別に違反しない
ありがとうございます。安心しました。
>(OutputIteratorを二つ引数に取るアルゴリズムは存在しない)
先読みするために内部でイテレータをコピー(現在の位置の保存、マーク)
されることがあるのかな、と思いまして。
またOutputIteratorを扱う処理を書く際にそういう仮定をしていいのかと思ったので。
>が、あまりお勧めはしない。
出来ればしたくないのですがshared_ptrの先のクラスが
ハンドル(OSの管理下)を持っているもので・・・。
>>96 規格ではそこまで規定してないみたいなので、自由にしていいのでは。
§24.1.2 [Note: The only valid use of an operator* is on the left side of the assignment statement. Assignment
through the same value of the iterator happens only once. Algorithms on output iterators should never
attempt to pass through the same iterator twice. They should be single pass algorithms. Equality and
inequality might not be defined. Algorithms that take output iterators can be used with ostreams as the destination
for placing data through the ostream_iterator class as well as with insert iterators and insert
pointers. .end note]
98 :
94 :2006/04/30(日) 15:27:01
2度通るべきじゃない、ということは94の例でいう所のst1を インクリメントしたら通り過ぎたはずのst2は参照するべきじゃない、 と考えて良さそうですね。 あと、leftで気付きましたが、OutputIteratorじゃなくてInputIteratorでした、すみません。orz 入出力以外の特性は同じですからいいんですが。
99 :
94 :2006/04/30(日) 15:38:33
VCに付いてくるSTLの<algorithm>眺めていると確かに規格の通り _FI(ForwardIteraot)と_RI(RundomAccessIterator)は複製してますが、 InputとOutputIteratorは複製している箇所はありませんでした。 これでいくつかの関数コールバック型の処理を 心置きなくイテレータ型に変えることが出来そうです。 ありがとうございました。
そういう実体を共有するような実装を許容できるために わざわざ InputIterator というコンセプトを導入しているとさえ考えても良いかと. ちなみに, InputIterator は複製自体が禁止されているわけではなくて, あくまで複製された複数の iterator オブジェクトが 同時に active になれないというだけなので. >入出力以外の特性は同じですからいいんですが。 あと,オブジェクト同士の同値比較(==, != 演算子)が要求されるかどうか という違いもあります.
101 :
94 :2006/04/30(日) 16:59:23
>わざわざ InputIterator というコンセプトを導入しているとさえ考えても良いかと. なるほど。 >あくまで複製された複数の iterator オブジェクトが >同時に active になれないというだけなので. activeというのは、st1をインクリメントしたらst2が無効(非active)で、 st2をインクリメントしたら逆にst1が無効になる、というのであってますか? 一つだけが有効という意味で。 >あと,オブジェクト同士の同値比較(==, != 演算子)が要求されるかどうか ホントだ・・・OutputIterator lastが見当たらない。 OutputIteratorの終わりは_szで指定するんですね・・・。勉強不足ですorz Outputだと思ってたfillはForwarditeratorでした。 ただちょっと聞いてください、Asciiの「標準C++STLの基礎知識」の 「アルゴリズムの想定する反復子」という章に template<class OutputIterator , class T&rt; void MyIncrementalFill(OutputIterator first, OutputIterator last, T n) { なんて例があるんですよ。本を鵜呑みにするなってことですね。
102 :
94 :2006/04/30(日) 17:01:18
× template<class OutputIterator , class T&rt; ○ template<class OutputIterator , class T>
InputIteratorなら、2個や3個を引数に取るアルゴリズムがたくさん 存在しているから、お互いに関連のあるイテレータを同時に渡すと 問題が起きるぞ。 それが意図した動作ならいいんだけど。
>>101 >ただちょっと聞いてください、Asciiの「標準C++STLの基礎知識」の
その本俺も持ってるけど、所々間違いがあるよ。P113で、OutputIterator
の特性の一つに「反復子の等式比較ができない」と書いておきながら、
P115のMyFill()やMyIncrementalFill()でいきなりfirst != endとかしてるし。
規格書通りにするとすれば、これはOutputIteratorではなくてForwardIterator
でなければならない。って、
>>101 さんは気づいているようですね。
105 :
デフォルトの名無しさん :2006/05/01(月) 01:55:02
諸悪の根元、また柏原か…orz
106 :
デフォルトの名無しさん :2006/05/01(月) 01:55:36
文系出身は本書くなよ
美しいC++プログラミング見本帖 わらた
C++ の本を選択するなら、悪いことイワンから Addsion Wesley 印のもの選んどけ。
初期のSTLも間違っていたんだから許してやれ と思ったが指摘されてるのが1995年だな やっぱだめだ
買っては逝けない本として列挙すべきものの一つだな
上の MyIncrementalFill でモチベーションの説明すると,上にあるように
MyIncrementalFill は現標準では ForwardIterator が必要になります.
しかし, MyIncrementalFill で要求されるのは「値を書き込めて」「次の要素に進められて」
「operator==, operator!= が定義されている(止まる位置を指定できる)」ことであり,
ForwardIterator では「値を読める」というアルゴリズムにとって無用な要求が
ついてきてしまう.こういうことは他のアルゴリズムでもありえます.このような問題を
排除して,各々のアルゴリズムの要求に適切にあった category を標準で提供したい.
なので,まず「値を読む/書く」と「iteration の位置の進め方」という
2つの直交した概念に関する要求を完全に分離した上で,
粒度をさらに細かくした分類を提供しよう,っていうのが n1477 の motivation ですね.
>111
現行と motivation が理解できてさえいればあまり混乱は起きないと思うんですけれどね.
現標準における category に対する後方互換性を完全に維持したまま,
category 分類の粒度が単に細かくなるだけですし.
あと iterator の concept に関する提案なら, n1477 ではなくて
http://www.boost.org/libs/iterator/doc/new-iter-concepts.html のほうが新しい revision なのでこっちを指したほうが良いと思います.
n1477 からさらに lvalueness に関する要求が直交化され,
また interoperability に関する記述が追加されてます.
これより最新の revision ってありましたっけ?
まあ現行の規格ではイテレータは5種類しかないからね。 それで特に気にした事はないけど、組み込みとかでメモリ要求 が厳しい環境だとそれすら問題になるんだろうね。 組み込みではSTLが使えない場合が大半だけど。
今まで生きて来れたのが寧ろ不思議なくらい。
なんだかstringに入れたパスの〜〜.mp3を〜〜.txtにメンバ関数replaceで置き換えて ifstreamにぶっこんでファイル表示させようとしても日本語の入ったものだけ開けない stringにマルチバイト入れて処理したらおかしくなる? std::string fn = GetPath(); fn.replace(fn.length()-3,fn.length()-1,"txt"); std::ifstream inf(fn.c_str());
ならない
ならifstream側がマルチバイトのパスに対応していない?
標準では未定義です。環境依存。
自分の環境ではifstreamが対応してないっぽい Cのファイル入出力使ったらすんなり通った
>>121 そりゃひどい実装だな。どの環境か晒してくれ。
ぶっちゃけlocaleほったらかしで日本語使えないとほざいてるに一票。
.txtが.txtである可能性について
いくら何でもそりゃねーだろ
127 :
117 :2006/05/10(水) 16:20:21
ロケールとやらの設定してなかった
そんなものあるんだな
ググって参考にしてみる
>>125 いくら俺でもそりゃねーだろ
>>115 10年前が華だったね
事務くらーくなつ仮死
STLやboostを実際に製品版設計に使っている所っているの?(ソフトハウスとか…)
>>131 STL を使ってるかってのは C++ を使ってるかってのとほぼ同義なのであたりまえにある。
boost について有名なところでは adobe とか。
>>132 >C++ を使ってるかってのとほぼ同義なので
んなこたー(ry
>>131 良い子はboostなんか使っちゃダメです、ママは許しませんからね
adobe って、boost 使って書かれてるの?まじ?
>STL を使ってるかってのは C++ を使ってるかってのとほぼ同義 そんなことない
>>136 頭の悪い指導者に「STL禁止」とかいうルールを強制されてる人ですか?
STLはいくらでもあるが、 実際にboost使ってるソフトなんてあったのか
>>140 あれ?違ったの?
そうでもなきゃ C++ 使ってて「STL使わない」なんて言う環境が思い当たらないんだが、
どんな環境の話?
>>141 組み込み系とかなら「頭が悪い」からじゃなくフツーにSTL禁止っつーか
使えない場合もあるだろ。
>>142 embedded C++ の話か?あれは規格策定者の頭が悪い。
そうじゃなきゃ「STL禁止」はフツーじゃない。アルゴリズムとコンテナをひとくくりにして
禁止にしてるあたりが頭悪い。
最近は組み込みC++でもtemplateをサポートすることが多くなったけど、 貧弱な組み込み機器だと、未サポートとか普通にある。
>>144 それ embedded C++ 掴まされてんじゃねーの?
HとかTとかが、「〜準拠」って売り文句を書きたいがために
策定したような規格だからな。
そこらへん意外だと大方 gcc が使えるから、最近は
template に制限のある環境もめっきり減ったと
思ってたんだけど、そうでもないのか?
そういえば Felica まわりで使われてなかったっけ? > boost
ま、 どうしてもSTLを使えない環境「も」ある どうしてもSTLを使わせてくれない糞プロジェクト「も」ある というところまでは来たかな。 自分が使えないことを「ていうか普通は使わないよ」でごまかす態度が 空々しく響く程度の浸透はしたね。
>>148 確かに5,6年前ぐらいだったら「いまさらそんなものが標準だと言われても・・・」な感はあったけど
いまじゃ使わない場合には少なくともその理由を求められる程度に市民権を得たね。
一口にboostと言っても内容が広すぎる。 shared_ptrあたりは結構使われてるんでないかね。ヘッダインクルードだけで使えるし。 Civilization4っていうゲームで、MOD作成用にCPU思考ルーチンのソースが公開されてるんだが、 boost::python使ってた。
embedded C++はWG21のperformance TRに葬られたも同然だな。
Mozilla系はいまだにSTL使っていないわけだが。
>>152 ソースgrepしたら
#include <vector>
#include <list>
#include <string>
とかゴロゴロ出てくる訳だが
WindowsCEはSTLをサポートしていないんだとか
>154 は?
STLはOSがサポートするものだったのか・・・
>>153 手元にあるFx1.5.0.3で見てみたけど、vectorとlistはembeddingとpluginと
wedgetでしか使われていない。その意味がわかって言ってるんだよね?
そしてstringはSTLではないよ。
>手元にあるFx1.5.0.3で見てみたけど 他のバージョンだとどうなったの?
> そしてstringはSTLではないよ。 出た出たw
いつのstringの話だ? STLが出来る前のstringの話か?
とりあえず貼っとく。
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++標準ライブラリだ。
範囲が明確に決まってるかのように、含まれるだの含まれないだの言うのは時代遅れだぞ。
このスレが不要である事に疑いの余地は無い。
テンプレートライブラリィかどうかでしょ
Mozillaクラスではboostは使えないのは分かるけどな boostどうこうではなくC++が実装されていない VC8さえまったく実装していない C++の致命的問題はC++言語を誰もコンパイルできないことにつきる
↑誰か翻訳して
>166 の致命的問題は、誰も >166 の発言内容を理解できないことにつきる
厳密な定義は知らないけど、 std::ネームスペースはSTLと言えるんじゃないかな。
coutもexceptionもSTL
coutもexceptionもstd::下ですよ。
標準の中で、stringは、 ・古いインターフェースを引き摺っているものの、 ・char_traitsによる制約が定義されていて、もっとも新しいスタイルの ・STLのクラス。
>>169 >厳密な定義は知らないけど
「ない」っつってんだろバカタレ。
>std::ネームスペースはSTLと言えるんじゃないかな。
stream I/O もか?バカタレ。
#include <cstdio> #include <cstdlib> : :
>>169 それは標準ライブラリ(Standard Library)と呼べば十分だ。
>>175 >「ない」っつってんだろバカタレ。
定義も見たこと無いし、「ない」っていうまともなソースも見たこと無いから
「知らない」って言ったの。
>stream I/O もか?バカタレ。
stream I/O もだよ。
実装ではchar_traitsなどかなりテンプレート使っているから、
自分で拡張するときは少なくとも「テンプレートのライブラリ」とは認識してたし。
俺がそう思ったのは、俺がSTLport使ってて、
STLportではstreamもstlというディレクトリの中にあるから。
というかSTLの範囲の定義が無いと言いつつstream I/OがSTLじゃ無いと断言出来るのは何で?
煽りじゃなくて、普通に知りたいんだけど。
>>178 175じゃないが。
コンテナ・反復子・アルゴリズム・関数オブジェクト・
およびそれらに対するアダプタのうち、
標準に含まれていて、ライブラリである(つまり構文ではない)もの。
...が大まかにSTLじゃないかと。
細部は人によるだろうけど、Scott MeyersはEffective STLで
「iostreamライブラリの部分」(「部分」は「一部分」だろうね)も
STLに含まれるとしている。istream_iteratorなどのことかと。
(個人的にはそれはちょっと違うような気がするが)
別の解釈としては、StepanovがC++にもたらした一連の部分がSTLである、とか。
書いてて
>>176 ともろかぶりになったが一応書き込んでおこう。
>>175 ではないが。
templateを使っていればSTLってわけじゃない。STLがtemplateを使っているだけ。
STLってのは(当初の定義としては)標準コンテナとそのイテレータ、
それらを操作するアルゴリズム(勿論標準のもの)のことを言う。
streamは標準コンテナじゃないからSTLとは呼ばない。
STLportに詳しくないから知らんが
>STLportではstreamもstlというディレクトリの中にあるから。
これはalgorithmの中の人たちがstream_iteratorを扱うから
問題起こさないようにSTLport側で統一しているんじゃないかな。
それと、STLの実装例の一つに過ぎないSTLportを挙げて
どうだこうだって言うのはあまり意味がない。
現在では実用上C++標準ライブラリと分ける必要性を感じない人もいる。
そういや ISO C++ にSTLって言葉出てきたっけ?PDFに検索かけられなくて卯剤。
参考
ttp://www.research.att.com/~bs/glossary.html#GSTL
181 :
180 :2006/05/12(金) 23:22:41
結局、個人とか本とかローカルな解釈のレベルでしか決まらないってことだろ。 どうでもいいじゃないか。
>>179-180 >コンテナ・反復子・アルゴリズム・関数オブジェクト・
>およびそれらに対するアダプタのうち、
>標準に含まれていて、ライブラリである(つまり構文ではない)もの。
>STLってのは(当初の定義としては)標準コンテナとそのイテレータ、
>それらを操作するアルゴリズム(勿論標準のもの)のことを言う。
なるほど。
今までコンテナなど以外にもtraitsやallocatorもSTLで、
こういう形で作られているライブラリ群をぼんやりとSTLだと思ってた。
あくまでコレクションライブラリ(集合の操作)としての
目的で作られた、ということか。
それならstringやiostream、exceptionが本質的にSTLじゃないというのは
納得出来る。
もやが晴れてきた気がする。アリガd
>参考
非常に参考になった。
>>182 何時までは夕方で何時以降が夜だ、と明確には言えないからといって、
夕方と夜の区別がどうてもいいとは言えない。
>>184 そうだね。でも STL に含まれるだの含まれないだのという区別はどうでもいい。
>>185 いや
このスレで取り扱う話題を規定する上で極めて重要w
となると、元の「STLは使っちゃ駄目だっちゃ」というラムちゃんの お告げは、何を使っちゃいけないのか?という哲学的な議論になる ということだね、さくらさん! その通りだ、あたる。
>>186 そうだね。こんなスレ早くなくなればいいのに、と思う。
心が擦り切れてる人が居るね
P.J. Plauger, Alexander A. Stepanov, Meng Lee, David R. Musser の
"The C++ Standard Template Library" では、
http://www.amazon.com/gp/product/0134376331/ <utility>, <iterator>, <memory>,
<algorithm>, <numeric><functional>,
<vector>, <list>, <deque>, <set>, <map>, <stack>, <queue>
<memory>と来たか…
>>190 コンテナを含めてアロケータを外すわけにはいかんだろ。
アロケータは脇にドケターワ
ここで扱うのはまあ、ここら辺はSTLって言う人居るなーってとこらへんでしょ?
>>190 コンテナのためのアロケータは別におかしくないだろ。
あと uninitialized_****
196 :
デフォルトの名無しさん :2006/05/13(土) 20:59:36
雑談半分です。 某解説本には、 pair<int *, int *> ret = mismatch(v1.begin(), v1.end(), v2.begin()); なるコードが載っているのですが、gnuやvisual studio ではコンパイルできません。 int * を vector<int>::iterator に変えると通ります(mismatchの定義からすると当然ですが)。 bcc32では通るようなんですが、int * で上記のコードを実装するのは、アリなんでしょうか。 (そもそもコンパイルできないものに実装もヘッタクレもないですけど) コンパイラの仕様の事情やなんかを教えて頂けると幸いです。
>>196 イテレータからポインタへの暗黙的な変換はサポートされてないだろ。
bccで通るのは、単にコンパイラが糞だから。
>>196 vector の設計意図としては vector<T> の iterator は T* で完全に実装可能あることが
容易に想像できる。そのせいで iterator と T* を混同するプログラマが多く発生した。
その問題への対策のほか、デバッグ目的のチェックを入れるためにも iterator を
クラスとして実装する処理系が増えてきた。
>>196 Borland C++のようにvector<int>::iteratorの実態がint*である処理系では、たしかにそれでコンパイルできる。
しかしvector<int>::iteratorがint*でなければならないとはどこにも定められていないのでg++やVC++の挙動でも問題ない。
おとなしく、int*をvector<int>::iteratorに替えるか、
それができなければv.begin()を&v[0]、v1.end()を&v[v.size()]、v2.begin()も&v2[0]にしろ。
>>199 &v[v.size()] は未定義動作にならないか?
組み込み配列では認められていたような気もするが、
vector では特にそんな特記事項は見たことが無いな。
>>197 >>198-199 も言ってるが bcc では iterator が T* で実装されてるってだけの話。
だから別に暗黙的な変換でもなければ、bcc の欠点というわけでもない。
>>200 そう言われればそうだな。&v[0] + v.size()ならいいか。
>>202 あーそれで問題ないな。規格の欠陥かとも思ったが、それで解決だ。
なるほど。。。 サンクス。
「vector<T>::iterator が T* で実装されている」ってどういう意味? typedef? typedefだと、iterator_traitsをpublicに出来ないから、 要するにvector<T>::iterator::value_typeなど、 標準には適合しないでしょ?
>>206 iterator 自体にメンバは要求されないよ。
iterator_traits<vector<T>::iterator>::value_type じゃない?
>>206-207 iterator_traitsに生ポインタ用の特別バージョンが存在する理由を考えよう。
ポインタという下位概念が、イテレータという上位概念になれないはずないでしょ。
ちなみにstring::iteratorもchar*のtypedefだね<BCC
ポインタはRandomAccessIteratorカテゴリのイテレータとして正式に使えます。
話ついでに聞きたいのだけれど、 イテレータ作るのって、 value_typeとreferenceとpointerとdifference_typeとiterator_categoryを定義して、 ++とか--とかを定義すればいいだけだよね? 手持ちの本にもWebにも情報が見つからない・・・
>>213 boost::iterator::iterator_facede 使いなよ。
六つmethodを定義するだけ。
> ++とか--とかを定義すればいいだけだよね?
これはたくさんあって大変だからさ。
216 :
デフォルトの名無しさん :2006/05/14(日) 21:13:44
>>216 二週間前から注文してるのにまだ届かないんだよ。
多分それは俺の所に来る分だった本だよ。よこせ。
>>217 うちはamazonで予約してたら4/30だか5/1だかに届いたけど
第2版も持ってるので読む気になれず放置してるや
>>218 オレも買ったが内容かなり違うから読んだ方が良い
>>178 こういう誤解をする人が後を勃たないから
せめてこのスレタイからは「Standard Template Library」の表記を
外して欲しいものだ
223 :
220 :2006/05/15(月) 15:33:03
>>223 スレタイの命名の議論を始めるには早すぎるということだ。
225 :
220 :2006/05/15(月) 16:52:11
でさあ、次のスレタイどうしよっか?
早漏は女の敵
遅漏は売女の敵
>>220 それをスレタイから外しても「STL」が入ってたら
>>178 のような人は無くならんと思うぞ。
逆に
>>180 あたりを要約してテンプレに入れればいいんじゃね?
>>180 見て気になって、規格を検索してきたが
STL
Standard Template Library
ともに記述は無かった。(大文字小文字の区別なし)
std::vector のメンバ関数 insert について質問。 insert(iterator pos, const T& v1); insert(iterator pos, size_type n, const T& v2); insert(iterator pos, IT first, IT last); insert を呼ぶときに v1 や v2 や [first, last) が自分自身の要素を 参照していたときでも、正しい挿入が行われることってそれぞれ保証されてる? std::deque の場合も気になるんだが、 deque は途中に要素を挿入すると反復子も参照も無効になるから、 insertを呼び出した時点でこれらが無効になると解釈すれば 「保証されない」という答えでいいのかもと思ってる。たぶん。
>>231 一番上は大丈夫だろ。
…と思ってgccの実装を見たら、メモリ再割り当てのときに拙そうだ。
>>231 上から順に O.K.,O.K.,ダメ です.
>>232 メモリ再割り当てのときは特に問題ないんじゃないですか?
in-place での挿入のほうが問題なはず.
でも確か GCC はちゃんと引数のコピー取ってから
要素をずらす実装だったように記憶しています.
>>231 23.1.1 -4-
Sequence requirements (in addition to container)
a.insert(p,i,j) ... pre: i,j are not iterators into a. ...
他の2つにはこういう事前条件は無い。
というわけで OK/NG は >233 のとおり。
Sequence で定義されてるから deque でもいっしょ。 list もいっしょ。
ついでに AssociativeContainer にも同様の制限を発見。
ほとんど全部だな。
235 :
232 :2006/05/16(火) 12:48:35
む、読み違えたか。失礼。
236 :
231 :2006/05/16(火) 19:55:56
STL準拠なカスタムアロケータが allocate(0) に対してどういう挙動を する必要があるのかって、標準で定義されてる? std::allocator<T> は ::operator new(std::size_t) を使う (つまりサイズが0でもヌルポインタを返すなどせず一意なポインタを返す)と 定義されているんだが。 カスタムアロケータについての記述が見つからんかった。 C++ IS: 20.4.1.1 -3- Uses ::operator new(size_t) (lib.new.delete).
>>238 さんくす。
しかしunspecifiedなのか…
>>239 実装する立場からすれば、何返してもいいってことだから楽になるんじゃないの?
それとも、アロケータを引数にするテンプレートでも書いてるのかな?
>>240 そう、アロケータを使う方を書いてる。テストするんでアロケータも書くんだけどね。
::operator new や std::malloc と同様に a.deallocate(a.allocate(0)) が
安全とされているかどうかを気にしている。
>>238 の通りallocate(0)の戻り値はunspecified、つまりnullになり得て、
一方で IS: 20.1.5 -2- の deallocate には
[Note: p must not be null. --- end note]
と書いてあるんだが… つまり、ダメってことか。
気になって調べてみたんだが、手元のlibstdc++(with gcc-4.0.3)や
STLport-4.6.2のvectorは n をわりとそのままアロケータに渡してる様子。
これだとstd::allocatorなら良くてもカスタムアロケータに対しては
安全ではないような。
自信なくなってきた。どこかで間違えたか?
>>241 あー。こりゃまずいね。
#199 の解決が新しい不具合を生んでるな。
- p shall not be null.
+ p shall not be null, unless n == 0.
こんな風に修正されるとでも期待していいと思うよ。
あれ? "must not" って書いてあった?
こっちで見てるやつは "shall not" になってるよ。
>>242 すまん。漏れが見ているのはISじゃなくてFDIS。適当すぎ。
ちゃんと入手するか…
>>237 > (つまりサイズが0でもヌルポインタを返すなどせず一意なポインタを返す)と
> 定義されているんだが。
これも便利な時あるのは分かるけど、
それを利用すると実装としてはトリッキーになりがちだよね。
>>241 のいうSTLportのvectorの場合、
サイズ0なのにアクセス可能な場所をポインタが指しているってことなので。
サイズ0ならポインタはアクセスしない方がいいので、
unspecifiedなallocatorの仕様の方がいいと思う。
あるいは例外を起こすか。
std::allocator がサイズ0に対して安全に動作するのは、 それを使うクラス群を効率的に実装するために有効だと思うけど。 例外なんてトンでもないよ。
ヌルポに反応しちゃう…
チンポに反応しちゃう
250 :
237 :2006/05/20(土) 01:43:15
>>245 > サイズ0ならポインタはアクセスしない方がいいので、
その通りではあるが、そのアクセスはそもそもプログラミングエラーなので
対処はいらない。問題はそこではなく、領域開放する箇所で発生する。
251 :
250 :2006/05/20(土) 01:46:28
問題のあるコンテナ。 (要素に対する構築/破壊とかいろいろはしょってるが気にしない方向で) template <typename T, class A = std::allocator<T> > class container { allocator_type alloc_; size_type n_; pointer p_; public: container(size_type n, allocator_type a = allocator_type()) : alloc_(a), n_(n), p_(alloc_.allocate(n)) {} template <typename In> container(In first, In last, allocator_type a = allocator_type()) : alloc_(a), n_(n), p_(alloc_.allocate(std::distance(first, last))) {} ~container() { alloc_.deallocate(p_, n_); } }
252 :
250 :2006/05/20(土) 01:53:07
問題が発生する用例。
template <typename In>
void foo(In first, In last) {
container<int> v1(0); // NG: deallocate(allocate(0),0)を行う
container<int> v2(first, last); // NG: 同上、first == lastのとき
}
…すまんさっそく間違えてるわ。
>>251 のコンストラクタ訂正
template <typename In>
container(In first, In last, allocator_type a = allocator_type())
: alloc_(a), n_(std::distance(first, last)), p_(alloc_.allocate(n_)) {}
インポは反応しない....
254 :
250 :2006/05/20(土) 02:10:27
コンテナの直し方の一例。 その1: container(size_type n, allocator_type a = allocator_type()) : alloc_(a), n_(n ? n : 0), p_(n ? alloc_.allocate(n) : 0) {} ~container() { if (n_) alloc_.deallocate(p_, n_); } その2: container(size_type n, allocator_type a = allocator_type()) : alloc_(a), n_(n ? n : 1), p_(alloc_.allocate(n_)) {} ~container() { alloc_.deallocate(p_, n_); } // 1より一見短いが、見かけ上のサイズや要素の構築を考えるといろいろ面倒 規格に厳密に従うためにはこのような条件判断が要求される、 ってのはまずいんじゃないかってこと。
>>252 その「問題」って具体的にはなに?
deallocate(allocate(0),0) って未定義だっけ。
256 :
250 :2006/05/20(土) 04:07:08
>>255 >>241 a.allocate(0) の戻り値 p は unspecified。0(null)になることもある。
p == 0 のとき、a.deallocate(p, 0) は 20.1.5 -2- 違反。
>>254 後者もreserve(1)を実行していると思えば悪くないと思う。
deallocate()しても大丈夫な特殊な場所を、 allocate(0)が返すってのは、いわゆる「番兵」方式だよね。 便利ではあるんだけど、オブジェクトの参照ってことを考えると、 かなり特殊な状況に陥るし、オブジェクト指向的じゃないよね。
>>258 番兵でもないし、オブジェクト指向とか関係ない。
どちらかというとNullObjectパターンに近いと思うが
>>258 番兵とは違うけど、利用側から見て特異点がないという点は共通している。
>>260 そうかも。何も処理しないとは限らない(余分なメモリ割り当てをするかもしれない)
ってところだけ違うという感じか。
>>257 std::vectorのようにsize()とcapacity()が異なってもよいコンテナならば、その通り。
でも、割り当てた領域のサイズと要素数が常に一致するような文脈では不便。
これって合法? template <typename Fwd> void foo(Fwd first, Fwd last); template <typename Fwd> void foo_dispatch(Fwd first, Fwd last) { foo(&*first, &*last); } // ← &*last は合法? ただし、Fwd はアドレスが連続する要素を指す forward iterator で、 last は何らかの有効な領域の終端( 要するに [first, last) )であるとする。 *last を読み書きするのは当然ダメなんだけど、 &*last でアドレスだけ取得するのはOKなのかな。 それとも、&*last のうち *last の時点で違法な参照外しになる?
>>264 多謝。FAQだったかorz
ダメってことね。
>>263 > ただし、Fwd はアドレスが連続する要素を指す forward iterator で、
「アドレスが連続する要素を指す」て、型システム無視してんじゃん。
if(first != last) foo(&*first, &*(last-1)+1); でいいのかね。
270 :
263 :2006/05/23(火) 00:34:44
>>267 説明が足りんかったが、既知の性質を持つ特定の反復子であることを
あらかじめ選別した上での処理、という話のつもりだった。次のような感じで。
template <typename GenericIterator>
void foo_dispatch(GenericIterator first, GenericIterator last)
{ /* 一般の反復子のためのコード */ }
void foo_dispatch(SpecificIterator first, SpecificIterator last)
{ foo(&*first, &*last); } // 問題の箇所、SpecificIterator専用コード
>>269 ご明察の通り first == last なら無処理でよい箇所だったので、
ほぼその通りのコードを書いた。まあでも不気味なコードには違いないので、
そもそもこういう処理をしないで済む構成にしようと検討中。
A∪Bを求める際、STLのsetを使えば一発でできますか? merge(A.begin(),A.end(),B.begin(),B.end(),C.begin()); ってやっても、うまくいかなかったです。
set_union
>>272 #include <algorithm>
#include <set>
using namespace std;
void main() {
set<int> a,b,c;
a.insert(1); a.insert(4);
b.insert(2); b.insert(4);
set_union(a.begin(),a.end(),b.begin(),b.end(),c.begin());
// 1 2 4 を表示したい
for(set<int>::iterator i=c.begin();i!=c.end();i++) printf("%d ",*i);
}
こんな感じでset_union使ってみましたが、
画面に何も表示されずに止まってしまいました。
mergeも同じでした。
一発で和集合を計算するのは無理なんですかね?
>>273 × set_union(a.begin(),a.end(),b.begin(),b.end(),c.begin());
○ set_union(a.begin(),a.end(),b.begin(),b.end(),inserter(c, c.end()));
↓このほうがいいかも。
c = a;
c.insert(b.begin(), b.end());
set_uion(a.begin(), a.end(), b.begin(), b.end(), ostream_iterator<int>(cout, "\n"));
>>274 set_union(a.begin(),a.end(),b.begin(),b.end(),inserter(c, c.end()));
でうまくいきました。ありがとうございました。
より直感的なc.insert(b.begin(), b.end())を使いたいのですが、
error C2664: '〜': 2 番目の引数を'〜::iterator' から 'const int &' に変換できません。
この変換を実行可能なユーザー定義変換演算子がないか、または演算子を呼び出せません。
と、エラーが出てしまいます。(VC++6.0)
ほかに何か#includeしないといけないんでしょうか?
msdnにもinsertの例が載ってたんですが、こぴぺしてもコンパイルできない;_;
>>275 うまく表示できました。ありがとうございます。
でも実際は表示の前に、変数に格納したいです。
>>276 c = a;
c.insert(b.begin(), b.end());
でうまくいきましたよ。それはおそらくVC++6.0であることに問題が
あるのだと思います。VC++6.0はメンバテンプレートに問題があるので。
バージョンアップをお勧めします。
>>277 c = a;
c.insert(b.begin(), b.end());
↑gcc 2.96でコンパイルしたらうまくいきました。
vc++6.0のほうに問題があったんすね。
set_union(a.begin(),a.end(),b.begin(),b.end(),inserter(c, c.end()));
↑で解決できたので、これでいこうと思います。
お付き合いくださった方ありがとうございました。
なんでまだVC6 (´_`)
問題があるのは分かってるけど、俺もVC6使ってる・・・
template使うんだったらVC6捨てた方が無難だと思うけど……
STL.NETはどうなったの? VC++2005には入っていないみたいなんだけど 消滅?
>>283 STL/CLIと改名したが、
VC++2005サービスパックに忙しくて、一時中断と開発者のblogに。
たぶんこのまま断ち消え。
286 :
283 :2006/06/21(水) 02:07:38
えと、.NET にコンテナクラスライブラリあったよね。 あれじゃだめなん?
うん、ダメ。ゴミ。
んじゃ、.NET er はどうすりゃいいんだよ!
今のところこんな感じ STL > Java New Collction > .NET Collction > STL/CLI(存在しない)
Dinkumwareの人がSTL.NETを作ってた気がするが
>>289 イテレータさえ自分で作れば大体何とかならないか?
できあがっても、たぶん、もっさり。
じゃあ俺はぽっちゃり
ぽっちゃり、とか言っておきながら、超デブと出会う日々だったりするこの頃。
1.79m-0.073Mgこれはどうだ?
class TBase { template<typename T> virtual void get(T *dat) { 処理; }; } class A : public TBase{}; class B : public TBase{}; class C : public TBase{}; vector<TBase*> list; : list[i]->get(何でも受け取れる); こういう処理をしたいのですが、templateはvirtual不可と怒られます。 どうか、お力を貸してください。
根本的にtemplateを理解してません。 templateの型はコンパイル時に決定されます。 本当に何でも入れる必要があるのですか? dynamic_castで何とかできるということはないですか?
>>298 virtual にする意味が判らんが、その前に STL とは関係ないな。
VC6で以下のコード実行したんですがうまくいきません int main() { std::string s = "あいうえお"; std::reverse(s.begin(),s.end()); std::cout << s; } 出力が おえういあ にならずに ィえういあ と文字化けします stlでは日本語使えないの?
int main() { std::wstring s = L"あいうえお"; std::reverse(s.begin(),s.end()); std::wcout << s; } だろうな
303 :
301 :2006/07/10(月) 01:46:03
>>302 即レスさんくす
やってみたけど今度は何も表示されなくなりました
そういえば wcout がまともに機能するコンパイラって、無いんじゃね? 少なくとも Windows では、 VC8 でも locale がバグってるし、 cygwin の gcc では元々サポートする気が無さそうだし。 他の OS では普通に機能してんのかな?
wcoutの関係か #include <iostream> #include <string> #include <algorithm> #include <atlbase.h> #include <atlconv.h> int main() { std::wstring s = L"あいうえお"; std::reverse(s.begin(),s.end()); std::cout << CW2A(s.c_str()); }
305はVC7で確認済み
307 :
301 :2006/07/10(月) 01:59:32
すみません STLでは日本語まともに扱えないってこと?
ワイドキャラクタで完全に扱える。 出力の時だけ、STL以外の手段を考えなさいということ。
>>302 std::wcout.imbue(std::locale(""));
が抜けてるぞ
なんでデフォルトのまま動作しないのかな?
311 :
301 :2006/07/10(月) 02:10:35
>>308 ありがとうございます
安心しました
で、以下のようにやってみたのですが
コンパイル通っても何も表示されません
#include <string>
#include <iostream>
#include <cstdio>
int main(void ) {
std::wstring s = L"あ";
std::string rs;
wprintf(s.c_str());
return 0;
}
基本的にstringからwstringへの変換は不可逆。 だから、 ロケールをいじってwcoutを何とかして使うか、 OSの機能で逆変換するか2つに一つでしょ。
>>310 禿同。
そう言えばこれってC++の規格上の問題なんだっけ?
それとも実装上の問題?
cygwinのgccだとwstringもwcoutも存在しないんだね・・・ 本家なら大丈夫?
デフォルトのロケールが"C"じゃないとそれはそれで困るだろ
いや、UNICODEの場合はロケールって関係ないべきでしょ。 複数の言語を混在して使えるんだから。
手元の[標準C++言語辞典]て本のwstringの項目に 「wstringは漢字の取り扱いに適さないのでstringを使え」 と書いてあるのですが、それ以上情報がない どういうことなの?
>>316 wchar_t をコンソールのエンコーディングに変換して出力する必要がある。
標準の範囲で考えれば、このエンコーディングがロケールに依存することは
十分考えられる。
Windows では直接ワイドキャラクタを出力する API があったと思うんで、
wchar_t のエンコーディングがこれに合わせてあれば変換は不要なはずなんだけどね。
WriteConsoleW使えばたしかにUnicodeそのまま表示できるが、 まともに動作するのはNT系だけだから、いちいち処理を9xとNT系で分けるようにする必要が出るし、 まあ、そこまでしてコンソールでUnicode使いたいという需要が存在したかといえば。
>>311 wcoutでもwprintfでも標準C/C++の範疇でASCII以外の文字を出力させるとしたら、
(少なくともWindowsとその他大抵の環境では)ロケールの設定が必要。
その方法はと言うと、wcoutに対しては
>>309 で、wprintfに対してはstd::locale::global(std::locale(""));。
必要なヘッダは<locale>。
これ位はたぶんVC6でも平気だと思う。
UNIXのgccやSunのccでは問題なし。
322 :
311 :2006/07/10(月) 09:31:07
>>320 ありがとう
以下でうまくいきました
<locale>のインクルードはいらなかったです
#include <string>
#include <cstdio>
int main(void) {
std::locale jp("japanese");
std::wstring s = L"ボンボン盆";
wprintf(s.c_str());
return 0;
}
せめてwprintf(L"%s", s.c_str());とかにしようよ、時と場合によるけど。
%lsじゃね?
wprintfなら%sは%lsと同等…だったと思う。
STLの質問でいいのかな? VC++でmapを使おうとするとどうも妙なエラーが出てきて通らない。 #include <map> #include <string> map<string, int> myMap; 既存のプロジェクトに上を追加しただけで大量の長文エラーの山になってしまいます。 昔から悩んでる割に深く調べずに配列の詰め替え処理とかに逃げてるけど 何が原因か知ってる人いますか? vectorのほうはまともに動くのになあ。
とりあえず、本当にそれだけしか書いてないのだとすればnamespaceで大量のエラーが出て当然。
おお、こんな時間にレスもらえるとは感激です!! 書き忘れましたが、このインクルードの上に#include"Common.h"してて そのなかでusing namespace std; もしてるんですよ。 (・・・vectorが使えなくてしばらく悩んでましたw) なので、vectorが使えるのに何でmapだめかなーと思ってました。
質問です。 STLを使ったプログラムのメモリ使用量を測定する方法はあるでしょうか? コンテナに測定用カスタムアロケータを指定する方法も考えたのですが、 コンテナが内部用に確保するメモリについてはカスタムアロケータは使用されない ようです。 もし良い方法をご存知の方がいらっしゃればお教え頂ければ幸いです。
>>326 エラーメッセージぐらいどこかにうpしろカス。
>>330 warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,
std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> > const ,int>,
std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int,
std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,
std::allocator<int> >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,
std::allocator<char> > >,std::allocator<int> >::_Node' : デバッグ情報で識別子が 255 文字に切り捨てられました。
このメッセージが延々出てきます。
ごめん、あまりに大量のメッセージが出るしトレース機能を調べるのも
面倒だったので実行すらせずにいたけどワーにングだったみたい。
一旦寝て、もう一度調べてみます。
たしかSTLのエラーを解析してくれるアプリってなかったっけ? あれに通せば分かりやすくなると思うけど、、、あれ・・・
>>329 アロケータ差し替えれば測定できるはず。
「内部用」にアロケータが使用されないってのはどうやって判ったんだ?
>>331 それはどうしようもないから、その警告は非表示にしていいよ。
>>328 ヘッダでグローバルに using namespace するのは良くないことですよ。
>>331 MSDNでC4786をキーワード検索すればすぐ出てくるやん。
ちなみにVS2003の C++のデフォルトではこの警告の出力はオフになってる。
未だにエラーと警告の区別が付かない子がいるのか・・・
>>333 要素型Tのコンテナにわたすアロケータの型はallocator<T>なので、
要素自身以外の内部データ(たとえばリスト構造や二分木)の領域確保
には使用されないと思いました。
allocator<T>::rebind<other>を使うだろ.
340 :
339 :2006/07/15(土) 09:05:47
rebind<U>::otherね。
ほんとにどうでも良いけれどテンプレート定義内では typename allocator<T>::template rebind<U>::other やね。この目的で使う template キーワードの代表例
342 :
デフォルトの名無しさん :2006/07/15(土) 09:46:29
なんだVC6、しかもC4786か。 悪い事は言わん、"C4786"でぐぐってみ。
あ、sage忘れたスマソ。
>339-341 ありがとうございます。試してみます。
おはようございます、331です。 ぐぐってみました・・・ orz 一応MSDNでは調べていたけど、てっきりビルドエラーメッセージを 切り詰めたものか何かと早とちりしてました。 ごめん、色々教えてくれてみんなありがとう。勉強になったよ。
>>345 キミのレベルだと、俺くらいになるまでに後100回くらい質問しないといけないな
この程度の試練は自力でクリアしろよ
ないところから無理やり煽るなよ
型Tの列コンテナで、サイズだけ指定して初期値を指定しないコンストラクタで 初期化した場合、初期化後の各要素の値は必ずT()に等しいって保証されてる? Tが非PODならT()になるのはわかるんだけど、PODのときはどうなのかなって。 つまり、例えばvectorなら const std::size_t n = 100; std::vector<int> a(n); としたとき、a[i] == 0, i:[0,n) は保証されてる? それとも std::vector<int> a(n, 0); と書かないと a[i] == 0 は保証されない?
>>349 その形で呼び出されるコンストラクタは
explicit vector(size_type n, const T& value = T(), const Allocator & = Allocator ());
と宣言されているから、 POD でもなんでも T() で埋まる。
>>349 > std::vector<int> a(n);
上で呼ばれるコンストラクタは、デフォルト引数を使っているだけで、結局下の初期化と同じ。
> std::vector<int> a(n, 0);
>>350 ,351
返答thx。
std::vectorのコンストラクタは確かに
explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());
で、dequeもlistも同じだった。(IS 23.2.1.1, 23.2.2.1, 23.2.4.1)
a(n)とa(n, t)をデフォルト引数を使って同一関数として実装するか別関数にするかは
実装次第と思ってたんだけど、規格で決められているとは知らなかった。
で、気にしていたのは、列コンテナ一般に対するrequirementsがどうなっているか
だったんだけど。IS 23.1.1 を見たら、そもそも a(n) が要求されていないのか…
>>352 Sequence には X(n, t) の要求があるよ。 23.1.1 (Table 70)
vectorのresize()は実行するまでに入っていたデータは 保障されているんでしょうか?
ああされるとも
>>354 100件データが入ってるのにリサイズで10にしたらどうなるか、ってこと?
質問させてください。 typedef struct Hoge { int nValue; BOOL IsCheck; }Hoge; vector<Hoge>vTest としてランダムな値をどんどん入れていき その後remove ? remove_if を使用して IsCheck がTRUEの場合の要素を削除するには どのようにしたらいいのでしょうか? 現在↓のようにやっていますが、数が多くなると遅くなってしまい使えません。 for( vector<Hoge>::iterator p = vTest.begin(); p != vTest.end(); ) { if( p->IsCheck ) vTest.erase( p ); else p++; } よろしくおねがいします。
listにする
bool operator()(const Hoge& h); の方がいいな。
362 :
357 :2006/07/22(土) 19:15:26
>>358 自分はvectorしか使ったことがないので
折を見てlistも検討してみようと思います。
>>361 あれからIsCheckでsortしIsCheckがTRUEの位置まで求めてeraseと言うことも試してみました。
やはりソートされているので早くなりましたが
>>361 までの速度は得られませんでした。
っていうかsortが出来たんならremove_ifだって出来てもおかしくないのに(´・ω・`)
ありがとうございました。
#include <vector> #include <algorithm> #include <cstdlib> #include <iostream> struct Hoge { Hoge() : IsCheck( std::rand()&1/*乱数の品質は気にしない*/ ){} Hoge( const Hoge & ) : IsCheck( std::rand()&1/*乱数の品質は気にしない*/ ){} int nValue; bool IsCheck; }; struct HogeChecker { HogeChecker(){} bool operator () ( const Hoge & h ){ return h.IsCheck; } }; int main( void ) { std::vector<Hoge> megahoges( 1000000 ); megahoges.erase( std::remove_if( megahoges.begin(), megahoges.end(), HogeChecker() ), megahoges.end() ); std::cout << megahoges.size() << std::endl; return 0; }
>>363 それじゃ全部生き残るか、空になるかの2択だな。
365 :
364 :2006/07/23(日) 12:38:31
あ、コピーコンストラクタでも rand() でとるのか。見落としてた。ごめんよ。
テラホゲス は無理だったかw
下記のソースについて質問です。下記に置いて、Aが実行された後、vCHoge[i] == CHoget[i] になるかと思ったところなりませんでした。 多分初歩的な質問だと思うのですが、本で調べてもよく分からなかったので教えて下さい。 class CHoge { private:int iKakaku; int iKosu; public:CHoge(void) {} ~CHoge(void) {} CHoge(int Kakaku, int Kosu ) { iKakaku = Kakaku; iKosu = Kosu;}}; class CHiHoge { public:CHiHoge(void) {} ~CHiHoge(void) {} void MakeTestData(void); vector<CHoge> vCHoge;}; void CHiHoge::MakeTestData(void) { const int iDataSize = 5; CHoge CHoget[iDataSize], *pCHoge; int i; for(i = 0; i < iDataSize; i++) { pCHoge = new CHoge( 1000, 20); CHoget[i] = *pCHoge; // CHoge[i]の初期化 } for(i = 0; i < iDataSize; i++) { vCHoge.push_back( CHoget[i] ); ---A } }
368 :
367 :2006/07/29(土) 03:26:20
ソースが変になってしまいましたので再投稿します。 class CHoge { private: int iKakaku; int iKosu; public: CHoge(void) { } ~CHoge(void) { } CHoge(int Kakaku, int Kosu ) { iKakaku = Kakaku; iKosu = Kosu; } }; class CHiHoge { public: CHiHoge(void) { } ~CHiHoge(void) { } void MakeTestData(void); vector<CHoge> vCHoge; }; void CHiHoge::MakeTestData(void) { const int iDataSize = 5; CHoge CHoget[iDataSize], *pCHoge; int i; for(i = 0; i < iDataSize; i++) { pCHoge = new CHoge( 1000, 20); CHoget[i] = *pCHoge; // CHoge[i]の初期化 } for(i = 0; i < iDataSize; i++) { vCHoge.push_back( CHoget[i] ); ---A } }
369 :
367 :2006/07/29(土) 03:32:10
環境はVC2003+MS純正STLです。
370 :
367 :2006/07/29(土) 03:54:53
大変失礼しました。自己解決しました。申し訳ありません。
std::multimap<int,std::map<string,int>>な変数使ってるとmapの中身が壊れてることがあるんですが なんかこういう風に使っちゃいけないとかって制限があるんでしょうか。 コンパイラはMinGWとCCで試してどちらも再現しました。
何がどう壊れてるいるのか説明
いや、そういう現象を聞いたことがある人がいるかどうかだけ知りたかった。
380 :
371 :2006/08/02(水) 12:06:18
>>378 どっちやねん!!
typedef std::map<std::string,int> MAP;
typedef std::multimap<int,MAP> MAP_ARR;
MAP_ARR map_arr_;
〜map_arr_への値の挿入とかあらゆる事を省略〜
const int Class1::accessMap(const string& str){
MAP_ARR::iterator istart;
MAP_ARR::iterator iend;
istart = map_arr_.lower_bound(step_);
iend = map_arr_.upper_bound(step_);
MAP::iterator target;
while ( istart != iend ) {
if((target = istart->second.find(str)) != NULL){
return target->second; // ここで壊れた値が帰る
}
++istart;
}
return -1;
}
説明がややこしいのでかなり省略。
まずはコンパイルしてみるという人にはすいません
map_arr_に値を挿入する時におかしな値を入れているってのはないことを確認しました。
>>380 find() の結果である iterator を NULL と比較してるのが間違いな予感。
>>381 多分それだな。2003のSTLだけど、end()でも真になる。
383 :
371 :2006/08/02(水) 13:22:13
>>381 ,382
ありがとう
findの見つからなかった場合の処理って
if (target == istart->second.end())
こうしないといけないんだね・・・
これで壊れた値は帰ってこなくなりました。
とんだDQNで申し訳ないです。
いや、多分自分がどっかおかしい事やってるんだろうなあと思ったんで
まず巷でよく聞く話か確認したかったんです・・・
>>374 ,375,377 うそつきーうそつきー
いや、うそつきでもないだろ。 別に371のようにバグがあれば、壊れることはいくらでもある。
386 :
371 :2006/08/02(水) 13:43:46
>>384 ごめんね、ただの負け惜しみだから気にしないで(´・ω・`)
387 :
デフォルトの名無しさん :2006/08/02(水) 18:33:01
vectorは低速確保高速利用 listは高速確保低速利用 って感覚ですか?
388 :
デフォルトの名無しさん :2006/08/02(水) 18:49:15
392 :
387 :2006/08/02(水) 19:57:37
395 :
387 :2006/08/02(水) 20:00:15
listのvectorに優越する点にはどんなのがありますか?
2文字短い
>>395 追加・削除を行っても、それまでのイテレータが無効にならない。
398 :
デフォルトの名無しさん :2006/08/02(水) 21:07:38
>>396 意地悪><
>>397 あり^^
いつもvectorばかり使うんですが、
list使わないとどうするのよって事例を教えて下さい。
LRUアルゴリズムの実装など。
>>398 listは途中の挿入削除のコストが定数時間でできるがvectorはそうはいかない。
まぁ、EffectiveSTLでも読んどけ。
401 :
デフォルトの名無しさん :2006/08/02(水) 21:43:36
頻繁に変更がある場合list 一度流し込んだらあまりいじらない場合vector ですか?
STLっつうよりデータ構造の基本です
実はデータ総数があまり多くなければ全ての用途においてvectorが最も速い。
>>398 コードを2文字短くしろって言われた場合
同じ話題をLOOP状態で繰り返してるような気がするのは俺だけなのか
406 :
デフォルトの名無しさん :2006/08/03(木) 08:45:52
>403 配列
>>403 データ総数が多くなってもそれだけでは遅くならんよ。
>>403 が言ってる「全ての用途」っていうのはinsertやdeleteを頻繁に使う使い方も含むんじゃないか?
complexityって理解してますか?
410 :
デフォルトの名無しさん :2006/08/03(木) 19:57:14
配列とリストの違いを考える事が本質ですか?
>>400-401 >listは途中の挿入削除のコストが定数時間でできるが
たしかにそうだが挿入すべき位置や削除すべきデータを見つけるために
list内を検索する必要があるのでは?
そこまで考えるとlistの検索は遅いのであまりありがたくないだろう。
>>411 検索フェーズと削除フェーズが分かれている用途は多い。
皆は STL のコンテナでどれぐらいの件数をハンドリングしてるの? 使ってるコンテナの種類は? それと、実装で苦労した点などもあれば是非。 俺はソート済 17 万件ぐらいを vector に突っ込んでるけど、更新はほぼ ゼロなので、気にするのは最初のロード時間だけって感じだな。検索は binary_search 使ってパフォーマンス的には全く問題なし。 便利な世の中だよね。
1億件ぐらいのvectorを多数使ってるが色々大変。 windowsは2GBの壁があるし。 はやく64bit時代が来て、メモリ20GBくらい普通に使えるようになって欲しい。
外部データベースを使えばいいやん。 適材適所って知らんのか?何でもオンメモリにすればいいってもんでもないだろ。
何でもオンメモリにすればいいってもんでもないが、 流体計算とかFEMなんかは普通オンメモリでやる。
そんな計算をWindows上でやるのがそもそもの間違いですがな。
どんな計算だろうが、外部データベースを使ってない時点で論外。
>>419 そんなことはないよ。
コスト的に、わざわざデータベースサーバを用意するのが割に合わない
ケースなんてザラにある。Webアプリじゃあるまいし。
421 :
デフォルトの名無しさん :2006/08/05(土) 04:27:41
いいよいいよ こういう議論をかいまみたかった
プログラムの要件に合わせて選べ、ってのが結論だろ。つまらん。
最近はCPUパワーでごり押しできるからvector以外とんと使わんなぁ。
自分も少し前まではバイナリサーチ絶対主義者だったのだが、 試しにデータベースを使ったら データベース > 素人バイナリサーチ な現実を目の当たりにして、考え方を変えた。 演算データのサイズは2GB程度で、バイナリサーチできない サイズじゃないんだけど、速度で負けた orz 検索アルゴリズムを勉強してアプリに特化したバイナリサーチを 組めば話は別だと思うけど、そこまでする気にはなれず、 データベース派の軍門に下った。
425 :
414 :2006/08/05(土) 08:11:00
>>415 ほー。興味本位なんだけど、1億の vector を多数ってどんなデータなの?
あ、ちなみに俺のは辞書ね。
>>424 コンテナ vs RDBMS ていうのもまあ面白い議論だとは思うけど、
どちらかと言うと「こんなコンテナの使い方してみたんだが、fuga が
hoge で gyabon だったぜ」みたいな生々しいケーススタディとかの
ほうが知りたいなあと。俺も普段 Oracle で業務システム組むことが
多いから、DB の良さもわかってるつもりだけど、それはまた別のスレで
やればいいことだしさ。
>>424 「アプリに特化したバイナリサーチ」て、
RDBの方はindexingとかcachingで速くなってるんだろ。
RDBMSは更新が激しいとCPUに思い負荷が掛かるので 同じ機械の他のアプリの速度が激減。
検索速度にこだわるならハッシュテーブルを使うべきだろう。 実際データが100万件だとバイナリサーチより5倍ぐらい早い。
5倍(w
たった100万件w
検索条件をHash化できればいいけど、そんな簡単なケースばかり じゃないし。WHERE 0<A AND A<1とか、どうやってHash化するよ? そもそもスワップしまくりのバイナリサーチなど意味ないし、 別マシンにDBを立てればバイナリサーチに使っていた CPUパワーを演算に回せるし。 ボーダーはCPU能力やRAM容量次第だけど、演算量やデータ量が ある規模を越えたら、DBを導入した方が間違いなくハッピーになれる。 無論、IndexやCacheを設定するのは前提。これをやらずに ブー垂れるのがいるが、見ていて痛い。
挿入削除が頻繁でなければいいのだが 時にはDB編成によるシステムの負荷がシステム全体の能力を落としてしまう。
433 :
デフォルトの名無しさん :2006/08/07(月) 18:17:45
コンテナは自身のクラスオブジェクトを何回ネストできますか?
>>433 処理系依存。テンプレートの入れ子と同じ事。
435 :
デフォルトの名無しさん :2006/08/07(月) 19:54:57
処理系とはOSの事ですか? コンパイラの事ですか?
両方
437 :
デフォルトの名無しさん :2006/08/07(月) 20:31:34
他に何がありますか?
。・。○。・。○。・。○。・。○。・。○。・。○。・。○。・。○ このレスをみたあなたは・・・3日から7日に ラッキーなことが起きるでしょう。片思いの人と両思いになったり 成績や順位が上ったりetc...でもこのレスをコピペして別々のスレに 5個貼り付けてください。貼り付けなかったら今あなたが1番起きて ほしくないことが起きてしまうでしょう。 コピペするかしないかはあなた次第... ○。・。○。・。○。・。○。・。○。・。○。・。○。・。○。・。○
>>432 挿入って言葉に反応してしまう自分が居ます
new
so, new
442 :
デフォルトの名無しさん :2006/08/08(火) 18:50:59
443 :
デフォルトの名無しさん :2006/08/16(水) 09:29:19
vc8でstlport5.0をコンパイルできません・・・orz Visual Studio 2005 コマンド プロンプトでbuild/libに行く nmake -f nmake-vc8.mak cleanの実行で良いんですよね? けどファイルが見つかりませんでできていないんですけど・・・
まさかnmakeにパスが通ってないって落ち?
Pimplイディオムでフィールドのpimpl_をstd::auto_ptrで保持していると 警告がでてきます(GCC 3.3.4)。 警告: invalid use of undefined type `struct XXXX::Pimpl' 警告: forward declaration of `struct XXXX::Pimpl' boost::shared_ptrで保持すれば警告はでないのですが何故auto_ptrだと でるのでしょう?それとも警告を出さないように工夫する必要があるので しょうか? class XXXX { struct Pimpl; std::auto_ptr<Pimpl> pimpl_; };
>>445 boost::shared_ptrは不完全型へのポインタも
きちんと正しいデストラクタが呼ばれるように保持するのだが、
std::auto_ptrはそうなっていないから。
448 :
445 :2006/08/16(水) 13:29:49
>>446 明示的にデストラクタを書いてやったら警告がでなくなりました。
boost::scoped_ptrも同じようですね。
>>448 ほとんどの auto_ptr の実装で、そういう結果になるんだろうけどねぇ。
仕様に明記が無い限り、標準テンプレートを不完全型でインスタンス化してはいけない。
やってしまうと未定義動作ってことになる。( 17.4.3.6 )
で、 shared_ptr は不完全型でも問題が起こらないと明記されている。
450 :
445 :2006/08/16(水) 14:00:53
451 :
↓質問。 :2006/08/26(土) 10:18:12
#include<vector> #include<iostream> using namespace std; class AA { public: virtualvoid test(void) { cout << "class AA" << endl ; } }; class BB : public AA { public: virtualvoid test(void) { cout << "class BB" << endl ; } }; int main(void) { AA aa ; BB bb ; vector <AA> arr ; arr.push_back(aa); arr.push_back(bb); arr[0].test(); arr[1].test();// "class AA" とでてしまう、なんで? return 0; }
arrに積まれてるのはbbのコピーのAAだから。 わかりやすく書くと arr.push_back(bb); の中で処理されてるのは概ね arr.resize(arr.size()+1); arr.tail() = bb; って感じ。 arrがぶら下げてるのはあくまでAAだから、そうなるのは当然のこと。 vector <AA*> arr ; arr.push_back(&aa); arr.push_back(&bb); arr[0]->test(); arr[1]->test(); を試してみるんだ。
453 :
451 :2006/08/26(土) 10:46:30
あースライシング問題か。 コンテナはいつも同じサイズのオブジェクトしか入れられないので、 boost::ptr_vector当たりも便利かもしれない。
STL使いなおまいらならGUI開発するときは何使う?Qt?WxWidget?
WTL
どっかのスレでSTLと親和性の高いWindowsGUIライブラリがでてたな。 UNICODE関連が不完全だったりしてたみたいだけど、どうなったかな。
WinSTL?
1年近く更新されてないけど大丈夫なんかね
大丈夫なわけがないだろう
boostになかったっけ?
非常に初歩的で恐縮ですが…vectorでの2次元配列についての質問です。 2次元配列を動的に変更したいのですが、 vector<vector<int>> v; v.resize( 100 ); for( vector<vector<int>>::iterator i=v.begin(); i != v.end(); i++ ) *i->resize( 100 ); のように記述すると、 error C2100: 間接指定演算子 (*) の使い方が正しくありません。 というコンパイルエラーが出てしまいます(Visual Studio 2005)。 for( i=0; i < v.size(); i++ ) v[i].resize( 100 ); のように記述すると、うまく動作するのですが、勉強を兼ねてイテレータを 使って記述したいのです。 どなたか、わかる方がいれば回答お願いします。
× *i->resize( 100 ); ◎ i->resize( 100 );
468 :
465 :2006/08/28(月) 19:39:49
>>466 素早い回答ありがとうございます!
解決しました。
469 :
465 :2006/08/28(月) 19:41:43
>>467 調べてたら>>演算子と間違えられるようなので
vector<vector<int> > v;
に修正しました。
が、>>でも一応コンパイルは通ってました
471 :
465 :2006/08/28(月) 20:36:23
申し訳ありませんが、質問ついでにもう1点お願いします。
>>465 で作った2次元配列をfstreamを使ってバイナリファイルでファイルに書き出したいのですが、
fs.write( reinterpret_cast<char *>( v[i] ), 100*sizeof( int ) );
のようにすると
error C2440: 'reinterpret_cast' : 'std::vector<_Ty>' から 'char *' に変換できません。
とエラーが出てしまいます。
(char *)v[i]
でキャストするとコンパイルは通りますが、動作がおかしいようです。
配列のようにv[i]で書いてはいけないのでしょうか?
&v[i]
473 :
465 :2006/08/28(月) 20:45:57
すいません、
>>471 の
(char *)v[i]は
(char *)&v[i]
の間違いです
&v[i][0]
回答してくださった皆様、ありがとうございます。
>>474 さんの書き方で解決いたしました。
STLというより、C++自体の勉強が足りないようですね。。。
お恥ずかしい限りです。
ありがとうございました!
476 :
デフォルトの名無しさん :2006/08/30(水) 11:34:08
STLとしては的外れな質問なのかもしれませんが、listのiteratorを、vector等のコンテナに格納するのは、できないのですか? こんなソースを描いてみたのですが、実行時に「セグメンテーション違反です」って言われます。 Linuxでgcc3.3でコンパイルしています。 #include <iostream> #include <list> #include <vector> int main( int argc, char **argv ) { { typedef std::list<int> int_list; int_list test_list; test_list.push_back( 1 ); test_list.push_back( 2 ); test_list.push_back( 3 ); test_list.push_back( 4 ); test_list.push_back( 5 ); std::vector<int_list::iterator> test_it_list; test_it_list.push_back( test_list.begin() ); std::vector<int_list::iterator>::iterator i = test_it_list.begin(); i ++; int n = *(*i); std::cout << *(*i) << std::endl; //セグメンテーション違反です } return( 0 ); }
>>476 test_it_listの要素は1つしかない
>>476 iteratorについて勉強してください。
479 :
デフォルトの名無しさん :2006/08/30(水) 12:41:27
すいません。 確かにひとつしかpush_backしていませんでした。 i++;を削除して、もう一度試しています。 どうも、iteratorには問題がなくて、coutへの出力に問題があるようです。 std::cout << "aaa" << std::endl; でも、セグメンテーション違反が生じましたので… お騒がせして、申し訳ありません。
>>476 iteratorの中身は、iteratorを無効にする操作によってコロコロ変化するから、
コピーをどこかに保存しておいても意味がないよ。
別々に保持しておきたければ、 そのたびにnewして別のiteratorとして持て。
list の iterator がそんなにコロコロ無効になるかな・・
>>480 list の iterator は変化しないよ。
>>476 int n = *(*i); //セグメンテーション違反です
485 :
デフォルトの名無しさん :2006/08/31(木) 03:26:02
>>476 オイラの環境では、なにごともなく、1が出力されました。
プログラムには問題ないのでは?
環境は、こんな感じ。
gentoo linux 2005.3 / kernel 2.6.15 / gcc 3.3.5 / glibc 2.3.4
それにしても、listのiteratorをlistとは別にもって、listの要素を処理をするのはなんだか違和感があります。
>>485 問 題 お お あ り だ ! !
>>477 をよくみろ!
std::vector<int_list::iterator> test_it_list;
test_it_list.push_back( test_list.begin() );
std::vector<int_list::iterator>::iterator i = test_it_list.begin();
i ++;
test_it_listのsizeは1なのにi++なんかしたら、iが指すのは範囲外だろ。
動いて見えてるのは単なる偶然だ!
でも
>それにしても、listのiteratorをlistとは別にもって、listの要素を処理をするのはなんだか違和感があります。
この感覚は正常。
こう書くべきですね。 #include <iostream> #include <list> #include <vector> int main() { { typedef std::list<int> int_list; int_list test_list; test_list.push_back(1); test_list.push_back(2); test_list.push_back(3); test_list.push_back(4); test_list.push_back(5); std::vector<int_list::iterator> test_it_list; test_it_list.push_back(test_list.begin()); std::vector<int_list::iterator>::iterator i = test_it_list.begin(); // i++; int n = *(*i); for (; *i != test_list.end(); ++(*i)) std::cout << *(*i) << std::endl; } }
>>486 > >それにしても、listのiteratorをlistとは別にもって、listの要素を処理をするのはなんだか違和感があります。
> この感覚は正常。
んなこたーないだろ。
エラー処理前回でやってみるとか
>>486 LRU (Last Recentry Usedだっけ)のキャッシュを効率的に実装しようとすると、
cache 内の item から List の iterator へのmapを持っておく必要がでてくる。
それ以外ではあまり必要を感じたことはないなぁ・・
あー、それは確かにやるかな。
492 :
デフォルトの名無しさん :2006/09/05(火) 22:30:16
趣味でやってるコードを、練習も兼ねてSTLを用いて書き直しているのですが mem_fun系がなかなか理解できません コンパイルが通らないのですが 構文が悪いのか、VC6.0のせいなのかわからないので ちょっと質問させてください 以下、コードを載せます なお、実際のコードでは vectorの中にはMEMFUNTEST::saveをオーバーライドした 派生クラスのポインタが詰まっています
#pragma warning(disable:4786) #include <vector> #include <algorithm> #include <functional> using namespace std; struct MEMFUNTEST{ virtual void save(FILE*fp)const{} MEMFUNTEST(){} }; int main(){ vector<MEMFUNTEST*>* data; data= new vector<MEMFUNTEST*>; MEMFUNTEST *ui = new MEMFUNTEST; data->push_back(ui); //↓これがやりたい #if 1 for_each( data->begin(),data->end(), mem_fun(&MEMFUNTEST::save) ); #else for_each( data->begin(),data->end(), mem_fun(reinterpret_cast<void (MEMFUNTEST::*)(FILE*) const>(&MEMFUNTEST::save)) ); #endif return 0; }
>>493 bind2nd(mem_fun(&MEMFUNTEST::save),stdout)
まだ標準の functional でなんとかなる範囲だな。
495 :
493 :2006/09/05(火) 23:27:34
>>494 回答ありがとうございます
GUIアプリなんで
FILE*fp;
//ファイルを開く
bind2nd(mem_fun(&MEMFUNTEST::save),fp)
としてみましたが、まだエラーが出てしまいます;
これはVCのほうかなぁ・・
http://www.wakhok.ac.jp/~sumi/stl/header/functional.html ↑こことかを参照しながら色々やってるのですが
mem_funを適用すると「何が残るのか」が良くわからなくて
苦戦してます^^;
bind2nd(mem_fun(&MEMFUNTEST::save),stdout)
この結果はオブジェクトなんでしょうか
bind2ndって確かbinary/unary_functionを継承しないと
ダメだったと記憶してるので
mem_funはテンプレート引数から
binary_functionを継承したクラスでも作ってんじゃないかと
想像してますが・・
>>495 gcc 3.4 では 494 でそのまま通る。 VC6 が怪しい。
エラーメッセージは?
497 :
493 :2006/09/05(火) 23:37:12
一応ですが、ソースの変更でのエラーです 見づらくなるのでstd::は取り除いてます error C2784: 'class mem_fun_t<_R,_Ty> __cdecl mem_fun(_R (__thiscall _Ty::*)(void))' :'<Unknown> 用のテンプレート引数を 'void (__thiscall MENFUNTEST::*)(struct _iobuf *) const' から減少できませんでした。
498 :
493 :2006/09/05(火) 23:41:45
>>496 ふむふむ。
となると、VC7.1や8だといけるかもしれないですね
うーぬ、書き直しは諦めようかな;
VC6 は template 周り結構もろいよ
VC6って確かメンバ関数テンプレートあたりが怪しくなかったっけ
502 :
493 :2006/09/05(火) 23:56:41
503 :
493 :2006/09/06(水) 00:23:06
>>501 のリンク先より
投稿元の方のコードはすんなり通りましたが、
自分の環境では、回答者のコードではエラーが出るようです
とりあえずコンパイルが通るやり方があるようなのでもう少し粘ってみて
また報告します
> std::for_each(v_.begin(), v_.end(),
> std::bind1st(std::mem_fun1<bool, A, int>(Func), this));
を
> std::for_each(v_.begin(), v_.end(),
> std::bind1st(std::mem_fun1(&A::Func), this));
と変更してみると、
先ほどと同じエラー
error C2784:
'class std::mem_fun1_t<_R,_Ty,_A> __cdecl std::mem_fun1(_R (__thiscall _Ty::*)(_A))' :
'オーバーロードされた関数タイプ 用のテンプレート引数を 'オーバーロードされた関数タイプ' から減少できませんでした。
がでました
504 :
493 :2006/09/06(水) 01:04:04
何とか、動作するコードになりました みなさんありがとうございました 変更点はMEMFUNCTESTで 戻り値をvoidからboolに変更 constをはずした の2点です >struct MEMFUNTEST{ >virtual void save(FILE*fp)const{} >.. から struct MEMFUNCTEST{ virtual bool save(FILE*fp){} //.. ループ部分 for_each( data->begin(),data->end(), bind2nd(mem_fun1<bool,MEMFUNCTEST,FILE*>(MEMFUNCTEST::save),stdout) );
>>504 VC6 で動かすのが至上目的ならまぁいいが、
標準 C++ で通らなくなってるのは痛い。
VC6 への呪いをコメントに込めて、普通のループに
展開しておくのがお勧め。
506 :
493 :2006/09/06(水) 01:12:23
reinterpret_castを用いて、constをはずさなくても動作するようになりました void→boolの変更は重要な変更ではなかったので 一応これで解決ということで。以下ソースコード #pragma warning(disable:4786) #include <stdio.h> #include <vector> #include <algorithm> #include <functional> using namespace std; struct MEMFUNCTEST{ virtual bool save(FILE*fp)const{ fprintf(fp,"year\n"); return true;} MEMFUNCTEST(){} }; int main(){ vector<MEMFUNCTEST*>* data= new vector<MEMFUNCTEST*>; data->push_back(new MEMFUNCTEST); data->push_back(new MEMFUNCTEST); for_each( data->begin(),data->end(), bind2nd(mem_fun1<bool,MEMFUNCTEST,FILE*>( reinterpret_cast<bool (MEMFUNCTEST::*)(FILE *)>(MEMFUNCTEST::save)),stdout) ); return 0; }
507 :
493 :2006/09/06(水) 01:16:40
>>505 標準C++で通らないってマジっすか!
VC6逝ってヨシ!金ない俺も逝ってヨシ;
508 :
493 :2006/09/06(水) 01:18:10
しかもyeahのつもりがyearになっとったw
>>507 標準に mem_fun1 という関数は無い。 mem_fun のオーバーロードで
同じ機能が提供されることになっている。
VS2005EE じゃ駄目か?
GUI なら駄目そうだな。
510 :
493 :2006/09/06(水) 01:30:12
>>509 なるほど、勉強になりますた
VC6で通るコードよりは標準で通るコードがかけるようになりたいですね
今回は普通のループ+コメント+呪いでお茶を濁すことにします
あと、VS2005は持ってないんです;すみません
素直に2005買っとけ。 普通で3万、EE落とした奴ならアップグレードの権利有りだから2万。 性能考えると安すぎる買い物だ。
512 :
493 :2006/09/06(水) 01:54:38
そうですね、お金貯めて買おうと思います^^
BOOST_FOREACH使えばいい 最先端かつ標準準拠のコードになりますよ
>>511 VC6もアップグレード元として有効だぞ。
コンソールだとただで手に入るような
516 :
493 :2006/09/06(水) 22:07:05
VS2005、30日だけのやつを落として実行してみました
もともとVCにあったSTLだし一応、コード自体は動きました
>>513 BOOSTは、STLもうちょっと理解してから挑む予定です
>>516 君のやろうとしてるSTLはすでに古いのでやっても無駄だ
Effective STLにもあるがその"異常"なコードを勇気をもって異常と言おう
いますぐBoostに挑め
518 :
493 :2006/09/06(水) 22:38:54
>>517 まじすか
mem_funとか理解に苦しむレベルで挑んで大丈夫なんでしょうか^^;
まぁとりあえずインストールからやってみます
>>518 標準にも見習えないところがいくつかあってだな。
mem_funは微妙にスルーでもいい気がする。
まあ腐っても標準なわけで、移植性が保証される点には高い価値があるけど。
やっても無駄ってのは言い過ぎだと思うが…。 mem_funとかの細かいとこにはこだわらずに便利そうならboost使うってスタンスはいいと思うな。 世の中からVC++6とgcc2.95が消えてくれればもうちょっと幸せになれる気がする…
521 :
デフォルトの名無しさん :2006/09/07(木) 00:13:08
boostには ・標準では届かないかゆいところに手が届くヤツ ・標準ではまるっきりサポートしてないヤツ ・新しいプログラミングスタイル提唱するヤツ と多種のクラスライブラリがあって、 事情で使っちゃいけない場合を覗いて、 最初のを知らないの損だと思う。
522 :
デフォルトの名無しさん :2006/09/07(木) 06:41:55
ベクタは確保が遅くて利用が速い リストは確保が速くて利用が遅い んですよね? 利用は参照のみと限定します。
524 :
デフォルトの名無しさん :2006/09/07(木) 07:51:02
>< ベクタは連続した領域を探すのに手間取る代わりに 配列なので高速アクセス リストは一個ずつ好きな所に確保してアドレス情報を記憶させて仮想的に連続したデータを用意だから いちいち広い所探さなくて良いので確保は速い その代わりアドレス情報を辿らないといけないのでアクセスは低速 って感覚だったですが違いましたか
こう考えるんだ。 vectorは連続した領域が必要だが纏めて確保できる。 listは非連続でもいいが一件ずつ確保しないといけない。 アクセスについても似たようなもんで、listのメリットはない。 ではlistのメリットは何かと言うと、操作のコストが低いこと。 要素の削除挿入が定数時間でできるがvectorはそうはいかない。 このスレ的には、先ずvectorで実装を試みて不満があるようなら dequeなりlistなりを使うことを検討すればいいだろう。 そのためにもvectorを配列的に使うのではなくiteratorで扱うこと推奨。 #詳細はEffectiveSTL参照で。
listが不適でvectorかdequeか迷ったらまずdequeの方を試すべし 最適化の目処が立ったらvector。
527 :
デフォルトの名無しさん :2006/09/07(木) 09:29:45
dequeをリッチにしたのがvectorですか?
528 :
デフォルトの名無しさん :2006/09/07(木) 09:35:43
一度こさえたら参照にしか利用しないデータ群なんですが、 vectorで合ってますよね?
検索とかするならmapとかの方がいいかも
ありがとうございました
deque ってあまり使うことがないのだが、どういうケースで役にたつのだろう
FIFO
>>528 ぶっちゃけvectorで全部いける。分けるとややこいしバグのもと。
ループは全部forだ。while(1)じゃワーニングでるのもあるっしょ。for(;;)って書いてる。
do while ()は使いませんか、そうですか。
カウンタが伴わないループはwhile(true)つー流派も有り。 極端な話、性能と再配置の制限が気にならないなら、大抵vectorで済ませられるのは、まあ同意。 順を追って覚えてけばいいんだしな。ちょっと触ればすぐ覚えることだし。
536 :
デフォルトの名無しさん :2006/09/09(土) 04:17:10
もういっそのことifとgoto使っちまわね?
規格書は有料?
>>537 基本的に有料。
英語のドラフトはダウンロードできる。
そして大抵ドラフトで十分。
540 :
デフォルトの名無しさん :2006/09/09(土) 11:54:27 BE:72306656-2BP(7)
>>539 それ、 C++ の規格表じゃね?
って、読んでないんだけどさ。
STL も含まれてるの?
>540 STL は C++ 標準に採用されてるんだから当然 C++ の規格表に含まれる。
>>541 あ、そうなのか。
俺、言語仕様とクラスライブラリとテンプレートクラスライブラリは
別々の規格になっているのかと思ってた。
C++スレから来たんですが、 あるクラスがコンテナに含ませることができるための 必要十分条件は、そのクラスが CopyConstructible かつ Assignable であること で良いんでしょうか?
>>543 あっちの書き込みで理解出来ないならこっち来ても同じ。
100件ぐらい追加・削除・参照するぐらいだと、ベンチ取ったら 全部vectorが速かったよ。
546 :
デフォルトの名無しさん :2006/09/09(土) 15:44:46
じゃあ100個以内ならベクタに無条件採択します
100件リザーブしとけば速くなるね
>>545 ただ単に追加とか削除とか言っても意味ないよ.
たとえば下みたいな vector に不利なベンチも簡単に設定できちゃう.
struct heavy_object {
vector<int> X;
heavy_object(int x) : X(10000,x) { }
};
vector<heavy_object> V;
for (int i = 0; i < 100; ++i) V.push_back(i);
for (int i = 0; i < 100; ++i) V.erase(V.begin());
list<heavy_object> L;
for (int i = 0; i < 100; ++i) L.push_back(i);
for (int i = 0; i < 100; ++i) L.erase(L.begin());
>>549 こういうのはstd::dequeの方が得意だな。
551 :
デフォルトの名無しさん :2006/09/10(日) 08:05:54
new T[] で確保した配列を、 std::vector<T> に放り込むってできます? やっぱり要素ごとにコピーするしかないですか? 内部表現がどうせ T の配列なんだったらできてもいいような気もするけど。
int* p = new int[100]; vecdtor<int> v(p, p+100);
553 :
デフォルトの名無しさん :2006/09/10(日) 08:43:19
>>552 それはつまり vector のイテレータが
実は配列の要素へのポインタであるということですよね?
STL 毎の vector の実装に拠らず、それは保証されている
ということですか?
そもそも vector は実際には配列を保持している、
というのは実装依存じゃなくて規格で決まっている?
>>551 assing() とか resize() とかで同じ結果になるんじゃないの?
>>551 もしそのvectorが独自のallocatorを使っていて
newで確保した領域を直に保持できてると
解放時にそのallocatorが割り当てたものじゃない領域を
allocatorに解放させてしまうことになる。
556 :
デフォルトの名無しさん :2006/09/10(日) 11:31:46
俺なんか勘違いしてた。
>>552 を実行すると、
激しくコピーが発生するんだね。
当たり前やん STLのコンテナはコピー渡しだもん
>>557 そ、そうか、そうだよね。
最初からコンテナとして確保するか、
boost::shared_ptr でもつかうことにしますは。
配列だからboost::shared_arrayだよ
>>559 コピーを嫌ってポインタのコンテナにするって話だろ。
>>560 いや、むしろコンテナでOOPをしたい時にはポインタを持つしかない。
>>561 だれも「コンテナでOOPをしたい」なんて言ってないわけだが。
>>563 それは、知識披露厨ってやつか。 C++ 相談室にも居なかったか?
独り言はチラシの裏にでも書いとけ。
と思ったけど、このスレをさっさと落とすのには役立つから、ここでなら別にいいや。
>>564 お前妙に突っかかるな。最近何か嫌な事でもあったのか?
>>565 最近 C/C++ スレで知識披露厨と呼ばれるウザイ書き込みが増えて嫌だなぁと思っている。
567 :
デフォルトの名無しさん :2006/09/10(日) 17:57:33
どっちが知識披露厨だボケ
>>566 そうか。お前は頭が悪いので、知識披露厨に負けない書き込みが
出来ないので、劣等感を感じているというわけか。せいぜい精進しなさいよ。
>>553 vectorのイテレータがポインタかどうかは実装依存。
メモリの配置はCの配列と同じであることが保証されてる。
&vec[0] で内部メモリの先頭アドレスが得られるからそこにmemcpyでも何でもすればいいよ。
ただしあらかじめサイズ調整しとくのを忘れずに。
そうするとsize()の戻り値が不正にならないか? コンテナは自分に何バイトコピーされたか知らないんだし
だから、サイズ調整するんじゃない?
size以下だったらただ要素が上書きされるだけでsizeは変化しない。 sizeより多くコピーしちゃだめからね。
574 :
571 :2006/09/10(日) 18:26:17
あぁなるほど reserveじゃなくてresizeしておけって事か
そういえばstringは
>>570 みたいな使い方が出来ることが保証されてるんだっけ?
あ、ダメみたいだ。解決しました。
ボインの乳首って、俺の性的な欲望のポインタだってことが分った。 ポインタは、ボインだ .....失敬
>>576 されてない。
だからC_str()がある。(→char []の変換)
>>580 されてないのか。
少しびびった。
c_str()は何を返してるんだと。
迂遠な実装なら、中にc_str()専用のポインタ控えてて
c_str()呼出し毎に中身を作り変えては、それを返してたとか
そんな風になってた可能性すらあったのか。
C++やるならEffective STLは絶対読んでおくべきでしょ。 レガシーAPIとのデータのやり取りについてとかも書いてあるよ。
stringってリファレンスカウントで実装できるんじゃなかったっけ
そういうのが多いね。
>>584 char[]の実体を共有している実装がある、
ってことですよね?
てことは
>>581 みたいになるなら大分効率が落ちるような…
vectorと同程度になるだけだから対した問題でもないのかな。
ん? 参照カウンタを使った実装なんて、昨今流行らないでしょ。
>>581 それ会議で1度も検討されていないみたいじゃないですか.
proposed resolution が出されているだけで.
>次の改定では規格に追記されるようだ。
と言うのはさすがに早計かなと.
レガシーAPIからstringにデータ直接渡せたら結構嬉しいけどな〜 vector<char>を経由させるたびに違和感を覚える。
StringBuffer<MAX_PATH> sb; GetModuleFileName(sb.GetBuffer(), sb.maxSize); string path = sb.toString(); のStringBufferみたいなバッファクラスを使えば?
手間だけから言ったら、new否定論者でもない限り char * sb = new char[MAX_PATH]; GetModuleFileName(sb, MAX_PATH); std::string path = sb; delete[] sb; でいいような気がするが。 #と言いつつ、自分だったらバッファクラスを作る罠。
・今時ポインタを生で持つとかありえない。例外安全とかどうするんだ →・boostにある配列用のスマートポインタとかもあるが非標準だし →→・いいからvectorにつっこんどけ
いや、スタックデータでいいだろ、別に たかがバッファ程度でvectorなんて、馬鹿の一つ覚えじゃあるまいし
スタックじゃニョキニョキできないじゃないですか
スタックならスタックでboost::arrayを使いたくなるBoost厨な俺。
たかがバッファが多くのバグの温床になってるのも事実。 というかnewの方が手軽だという感覚がわからん。vectorの方が手軽で安全じゃね?コードも見やすくなるし。
間を取ってboost::scoped_arrayで。 まぁboostなのが微妙に嫌だけど
もう数年待てばおそらくarrayもscoped_arrayも標準入りしているはずだ。
>>601 vector があるんだから scoped_array が標準入りすることは無いと思うよ。
603 :
デフォルトの名無しさん :2006/09/11(月) 23:22:09
>>592 はすごく効率悪いしわざわざ自作するのもなんかね。
>>593 みたいだとさすがにdeleteがめんどいとは思わないけどMAX_PATHみたいなバッファのサイズをプログラマ側が管理するのは結構危険だと思う。
やっぱりvectorかな〜
>>589 検討されたかどうかなんてわかるのか?
とりあえず "Status: Ready" だから、 LWG では話がついているようだ。
そっから先、改定までのプロセスはよくわからない。遠いの?
長すぎる文字列は rope にでもして、string は実質 vector<char> にしてほしい。
>>605 なんだっけな。c_str()の実装を簡単にするために、最後の要素が'\0'に
してあるだけのvector<char>式の場合が多いそうだ。
おまいらも早く大人になってBoost覚えろよ
Boostに文字列クラスなんてあったっけ?
>>604 あ,すいません. Status: Ready を完全に見落としてました.
こちらのバカチョンです.なぜか New と混同してました.
>そっから先、改定までのプロセスはよくわからない。遠いの?
自分も改定までのプロセスは581のリンク先に書いてあるとおり
「LWG の投票で DR に採用 -> WG の投票で TC か WP に採用」
ぐらいにしか理解してないです.
610 :
592 :2006/09/12(火) 11:11:09
>>603 >>592 って効率わるいかな?こんなクラス想定してるんだけど・・・
template <int SIZE, typename T = char> class StringBuffer {
T buf[SIZE];
T* getBuffer() { return buf;};
basic_string<T> toString() { return basic_string<T> (buf); }
};
toString は効率悪いか。格好悪いがgetBuffer()だけでいいか。
toStringは効率悪いと思う。だからといってgetBufferだけにするならarrayと何も変わらないし。
>>610 効率以前に、クラスを作ること自体が無意味。
どうせ作るなら、バッファサイズの指定がいらなくて、toStringしなくてもOKというものでないと。
>>612 typedef char[MAX_PATH] PathBuffer;
とかしとといて、この手の(path格納、操作用)用途では string 使わないとかか。
悪くないような気もする。
配列をtypedefするといつかアホが PathBuffer* pb = new PathBuffer; delete pb; なんてする悪寒
delete[] pb; にしろっていう意味?
配列をtypedefすんなバカ って事では
>>615 >>617 それって良く言われてるけど
delete[] pb;
を
delete pb;
した場合どんな実害があるの?
メモリ管理の実装によるだろうけど 多分配列の先頭しか開放されない あるいは管理領域を破壊するかもしれない
鼻から悪魔が出るかもしれない。
#include <iostream> struct A{ A() {std::cout << "create" << std::endl;} ~A() {std::cout << "destroy" << std::endl;} }; int main(){ typedef A Arry[10]; A *a = new Arry; delete a; } 結果 > create > create > create > create > create > create > create > create > create > create > destroy とりあえず gcc だとこうなった
typedef A Arry[10]; Arry *a = new Arry[1]; delete a; create create create create create create create create create create destroy destroy destroy destroy destroy destroy destroy destroy destroy destroy
素直にvector使えばいいのに
625 :
デフォルトの名無しさん :2006/09/13(水) 23:29:55
次のコードがGCC4.0, XCodeの環境でコンパイルできません。 ある本にあるままのコードなんですが。。。 理由を教えて頂ければ幸いです。 よろしく御願いします。 class gen_rand : public std::unary_function< unsigned int, unsigned int > { public: unsigned int operator()( unsigned int limit ) { srand( static_cast<unsigned int >( time( NULL ) * 100 ) ); return rand() % limit; }; }; メイン関数の中で、 std::random_shuffle( str.begin(), str.end(), gen_rand() ); エラーメッセ error: invalid initialization of non-const reference of type 'gen_rand&' from a temporary of type 'gen_rand' error: in passing argument 3 of 'void std::random_shuffle(_RandomAccessIterator, _RandomAccessIterator, _RandomNumberGenerator&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _RandomNumberGenerator = gen_grand]'
gen_rand()のカッコの中に最大の数を入れなきゃだめなんじゃないの?
> c++/include/bits/stl_algo.h では template<typename _RandomAccessIterator, typename _RandomNumberGenerator> void random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomNumberGenerator& __rand) と定義されてるので std::random_shuffle( str.begin(), str.end(), gen_rand() ); の gen_rand クラスの参照渡しがひっかかっている。 class gen_rand_class : public std::unary_function<unsigned int,unsigned int > { public: gen_rand_class(){srand( static_cast<unsigned int >( time( NULL ) * 100 ) );} const unsigned int operator()(const unsigned int& limit ) const { return rand() % limit; }; } gen_rand; int main() { ... std::string str="123456789"; std::random_shuffle( str.begin(), str.end(), gen_rand ); ... } とりあえず、こんな感じにするといいと思う。 random_shuffle の方を const 参照にしてしまえば楽だけど、これはあぶないのかな?
operator ()を呼ぶ度に、擬似乱数の内部状態は変化するはずなのだから、 operator ()がconstであっては意味的におかしい。 一方で、値渡ししていては、(単純な実装では)内部状態が引き継がれない。 だから、random_shuffleの3番目の引数はconstでない参照となっているのではないだろうか。
>>625 temporaryにするからconstnessでひっかかる。本も古いでしょ。
gen_rand gen;
std::random_shuffle( str.begin(), str.end(), gen );
空気を読まずに、俺の愚痴を聞いてくれ。 VS2003付属のstringの中を漁ってたんだ。 前から思ってたんだが、MSのSTLのコードは変な上に汚くて、無駄に複雑で、そして非効率。 まあ性能の問題はとりあえず追いといてもいいし、普段STLの内側なんて見る必要ないんだから ソースがド汚いのも、それはそれでいい。 同じ関数のオーバーロードで、範囲チェックが片方はクランプして片方が例外投げるなんてのも 何か深遠な理由があるんだろう。使い方間違えさえしなければ出くわさないから気にしない。 たとえ無駄に二重にチェックをしている場所があったとしても、運がよければコンパイラが 消してくれる可能性もあるだろう。気になるけど、気にしない。 けど、const_iteratorを継承してiteratorをでっちあげた挙句、初期化でconst_castを使うとかの 滅茶苦茶な実装、これは許していいものなのか。 初めてみた時には目を疑ったよ…知らぬがフラワーってまさにこのことなんだな…
632 :
デフォルトの名無しさん :2006/09/14(木) 07:03:18
626〜630の皆さんありがとうございました。
>>631 const_cast を使っても、その結果によって実際に const として定義されたオブジェクトを
書き換えてしまわなければ、未定義動作にはならない。
コンテナ内のオブジェクトはすべて、ヒープ上に非 const オブジェクトとして
生成されているはずなので、それを知っているコンテナの実装が内部で使う分には
まぁ問題ないと思われ。
この理屈で const_cast を正当化するとしても、その旨コメントは欲しいところだね。
VS2003入れてんだけどgrepっても
>>631 がいうようなコードが見つからなかった。
どにあんの?
これかな? Microsoft Visual Studio .NET 2003\Vc7\crt\src\xstring class iterator : public const_iterator { reference operator*() const { // return designated object   return ((reference)**(const_iterator *)this); } _Tptr operator->() const { // return pointer to class object return (&**this); } ...
MFCのEditクラスのソースを見てクラクラしたのを思い出す
MSの社員はコードの美しさよりも作業効率が優先されるから仕方ないしょ オープンソース系の連中は思いっきり時間がかけられるから、美しく綺麗なコードが多いのかもね ビジネスは効率と結果が命、オープンソースは美しさとプライドが命
>>638 そのことは聞いた記憶がある。。
随分長いこと裁判で揉めてたんだっけ。
VCにおけるSTL関連の冬の時代、長かったよね。
いやまあなんつーか、STLは性質上コードが剥きだしになるしかないから
わざとあんな書き方になってるのかもしれないけれど、異常な読み辛さ、
迂遠な実装、エトセトラはなんなんだろうね。
イテレータ同士の引き算でdeference_typeを得るのはいいんだが
そこで負になったのをsize_typeにブチこんでサイズチェックを
無理やり突破してるのとか、全編そんな調子でござるよ。
erase()でイテレータの前後を間違えたとかいうのは、
そのまま未定義動作でいいのかもしれないけど、
それにしてももうちっとなんとかならんのかと。
結果オーライ上等で構わないんだけどさ。
以上、ご清聴ありがとうございました。
>>639 最新のBorland謹製C++(BDS2006、TurboC++Pro)でも実は
Dinkumwareが使われている。
xstringを読んでみたら、なんか一から書き直されているようで
>>635 に相当するような構造にはなっていなかった。
VC2005もついでに調べてみたら、Borlandのとよく似た書き方
になっていた(当たり前か)。
BolandもDinkumware製なのか。 少し驚いた。 いま2005のxstringを軽く読んでみたけど、 2003のそれとは全然違うね…つーか最初から こう書いてくれって感じだ。
Borlandは一度STLportに見切りを付けられたから、Dinkumwareに 仕方なく金払ったんだろうな。 しかしここに来てSTLportにBorlandサポート復活の兆しがあると いうのも皮肉な話だ。
BorlandはRogueWave>STLport>DinkumwareってSTL実装かわりすぎだな。
646 :
デフォルトの名無しさん :2006/09/20(水) 00:24:28
>>644 彼のせいでマイクロソフトのvs2005はとてもクールになっちゃったんだよな
c#とかASP.NET2とか
C++関係の本が山の中から出てきた。来週はこれを捨てよう。 C++を勉強している若い人は人生を無駄しないように別の言語も考えたほうが良い。perlとか。 Javaも同じ。
pu
>>647 そうか。それはそれでいいが、このスレに書き込みしてスレを浪費すんなヴォケ。
保守
>>511 >>普通で3万、EE落とした奴ならアップグレードの権利有りだから2万。
ほんとうですか?
microsoft って昔からタダの製品からの優待販売とかよくやってるよね。
>>654 おまけPhotoshop LEはただではない。
>>644 ビデオ観たよ
DB開発のスタイルが変わっちゃうなあ
俺もC#勉強しとこ
>>652 ありがとうございます。
実際に 2005 Express から Standard に Upgrade なさったかたはいますでしょうか?
シリアルナンバーもないのにどうやって Upgrade してインストールするのでしょうか?
>>657 は?なんでシリアルナンバーがないの?
Express をインストールするときにプロダクトキーが要るじゃん。
もしかしてまだ Express Edition をインストールしたことがないの?
659 :
デフォルトの名無しさん :2006/09/23(土) 17:31:28
Visual C++ 2005 Express Editionのことならプロダクトキーいらない
アップグレード版についてくるシリアルを普通に入力してインストールしたが…
>>660 ありがとうございます アップデート版を買ってきて インストールできなかったら
どうしようかと悩んでいました。
stringってNULLを表現できないのですかね?
NULLを表現ってのがなんのことかわからんが、 NULL文字代入したいだけなら、 string s; s.resize(1); s[0] = '\0'; とかはできるだろう。 length()とc_str()の関係が崩れるし、もしかしたら実装依存かもしらん。
char * p = 0; if (p != 0) { ... と同じことを、stringでやりたいってことじゃない? 厳密なNULLとは違うけど、string*でやるか、空文字か判定すれば?
664のようなことをやりたければ、boost::optionalがある。 だめか?
空文字判定で十分だろ。 確かORACLEとかでも空文字はNULL扱いだった気がする。
だな。if(!p){
if(p){
え、空文字で if (p) って判定できるの? 知らんかった、後で試してみる
細かいことだが,「空文字」と「空文字列」の区別はしような 「NULL文字」とか・・・
まったくもってごもっとも。 えーと、つまりstd::string には operator bool() const { return !empty(); } 的な何かが定義されてるから、空文字列か否かは if(!str) で判定できるって話でOK?
日本語でおk
C++でおk
無いよな。 いや、おかしいとは思ったんだよ。 使った記憶ないし。
つNullableString
宣伝乙
>>662 s.length() == 0がNULLチェックに相当。
basic_string::empty()を忘れないであげてください…
まあ、大抵中身は
>>680 なんだけどさ。
682 :
デフォルトの名無しさん :2006/09/28(木) 23:16:07
質問です。 std::stringstream sstr; sstr << "test string"; などとして、sstrにデータを入れた後に、不要になった内容を破棄するにはどうすれば良いでしょうか。
683 :
デフォルトの名無しさん :2006/09/28(木) 23:23:18
質問です。 STLが邪魔臭くて、DEBUG_NEWでメモリリークが検出できません。 メモリリークを検出するにはどうしたらよいでしょうか? VCの警告レベル4でコンパイルすると警告が出まくるのは仕様でしょうか?
警告のでないコードに書き換えましょう。
>682 sstr = std::stringstream(); か sstr.str( std::string() ); ぐらい
686 :
685 :2006/09/28(木) 23:39:00
ごめん >sstr = std::stringstream(); これ忘れて
>>684 駄目です。
そもそもSTLのソースで警告がでまくります。
>687 再現する最小のコード曝せる? releaseビルドで最適化の結果コードが削除された云々な警告なら知ってるんだが
>>688 VCの警告レベル4に設定してる?
#include <vector>
ってやるだけですげー警告が出まくるんだけど?
>689 6.0?
いやもしや8.0か?
2005EEでnamespace使うとでるやつかな releaseで回避してるけど、解決法有るなら俺も知りたい
脳内フィルターで消す。どうしても気になるならコンパイラオプションで消す。
>>692 無償版と有償版で使っているSTL違うの?
>>682 放っておいても stringstream のオブジェクトが
スコープからはずれたときに勝手には気されるんでわ?
その前に明示的に解放したいってこと?
ところで stringstream から str() で string を
取り出すところでは当然コピーが発生してますよね?
>ところで stringstream から str() で string を >取り出すところでは当然コピーが発生してますよね? 空stringのコピーがな。 十中八九単純な初期化と変わらん処理に化けるだろう。
>>683 まさか DEBUG_NEW を定義した後に #include <vector> ってやってるとか?
ここ STL スレだし、そんなはずないよね。
>>697 いやいや、やってるやってる。
どうしたらいいのか教えてくれ!
STL自体のリークを疑ってるのか?ひょっとして
>>698 結論から云うと、STLヘッダは stdafx.h でインクルードすればよい。
MFC の DEBUG_NEW マクロは new を new(_NORMAL_BLOCK, __FILE__, __LINE__)
相当のものに置換することで new した時のファイル名と行番号を記録するものだが、
こいつを定義した後に vector をインクルードすると vector で使われている
placement new を置換してしまい、結果コンパイルエラーとなる。
何もいじってないのにコンパイルに失敗するとかは環境依存スレに聞いたほうがいいよ。
>>700 おお!ありがとう!
そうだったのか・・・ということは各ソースでインクルードしてるSTLのヘッダを削除して
stdafxで定義しなおす必要があるのか・・・激しく鬱だ・・・orz
(´・ω・`)<でもメモリリーク発見に手間取るよりいいよね。ありがとう。
標準のヘッダはstdafx.hでインクルードするもんだと思うぞ、VC++では。 そうしないとプリコンパイルドヘッダの恩恵が受けられないし。
わざわざ明示しなくても勝手に判断してプリコンパイルヘッダ機能使ってくれればいいのに。
そんなことされたら訳わからんバグに悩まされそう
普通に #include <vector> #include "stdafx.h" とすればプリコンパイルされると思うのだが。
>>701 ようするにDEBUG_NEWがヘッダより後に定義されればいいので
別にstdafxに全部持って行かなくても順番変えればいいだけだぞ。
されません。
>705 VC++ではプリコンパイルドヘッダを使うとき、 stdafx.hのインクルードよりも前にある全ての字句要素は無視されるという仕様。
わざわざ stdafx.h とか指定しなくても #pragma hdrstop あるんだから それだけでプリコンパイルヘッダ使ってくれればいいと思います。 BCC ってそういう仕様じゃなかったっけ?もう何年も使ってないからいまはどうか知らないですが。
>>709 BCBならstdafx.hの代わりにbasepch.h使ってた。
711 :
デフォルトの名無しさん :2006/10/01(日) 16:39:41
日本人は低能知能なのには呆れますね。 私達中華人民はあなたたちの掲示板を拝見して笑ってみてますよ。ではありがとうございました。
塩まいとくか、自由 平等 天安門
もっと辛い塩まくか、台湾独立
もっと塩撒いておく、チベット独立
こんなとこで思想振りまくより、もっと生活一般で話してるやつのとこのほうが引っかかる率が多いぞ
天安門って向こうで通じるのかな? 向こうでは六四事件じゃ?
712-714じゃないけど、天安門みたいなキーワードがあるページは、検閲されて中国のネットから 繋げないらしいよ。
単純な質問ですが、 vectorでまだ要素が10しか入っていないのに vector<hoge>::iterator itr = vechoge.begin(); advance(itr, 20); vechoge.insert(itr, objhoge); とかしたらどうなるのでしょうか。
>>720 明快な回答ありがとうございます。
また質問なのですが、Vectorのコピーって、中身の要素のコピーまできちんとされるのでしょうか。
参照のようなものだけコピーされて、結局Vector Aと Vector Bで B = AとかB(A)したら
結局両方とも同じ中身の要素をさしてたとかならないんでしょうか。
>>721 それは無いから安心しろ。但し、std::vectorの中身がポインタだったら、
それが指す先まではディープコピーしてくれない。当たり前だが。
>>721 23.1.4.1にN回要素型のコピーコンストラクタを呼ぶと明記。
すみません。また質問です。 vector<ObjectA> vec; vec.clear(); とすると、vecに入れた全てのObjectAのデストラクタが呼ばれてObjectAは破棄されると考えて良いのでしょうか。 それともObjectAへの参照のようなものがなくなるだけで、入れたObjectAは宙ぶらりんになってメモリリークしてしまうのでしょうか。
Googleで調べれば一瞬で分かるつまらないことを何故わざわざ2chまで質問にくるんだ?意味不明。
「破棄」て微妙な表現やなw
構築/解体 生成/破棄 普通じゃないか?
>>726 自分のために誰かが改めて労力を割くところを目の当たりにすると、
自分がすごく偉くなったようで気分が良くなるからじゃない?
すみません、auto_ptrについて質問させてください //こっちはOK typedef auto_ptr<int> iptr; iptr ok(new int(3)); cout << *ok << endl; //こっちはコンパイルが通るのにNG iptr ng; ng = new int(5); cout << *ng << endl; 下側のような使い方をしたいのですが こういう使い方は無理なのでしょうか
>>733 おお、できました!
iptr ng;
ng.reset(new int(3));
cout << *ng << endl;
ありがとうございました
735 :
デフォルトの名無しさん :2006/10/05(木) 19:27:21
string の c_str のように、vector<> のなかを配列として覗くことは出来ないのでしょうか?
736 :
732 :2006/10/05(木) 19:27:38
連続で申し訳ないですがもう1点だけ気になるところがあります auto_ptr<int> a(new int(3)); int i = 5; a.reset(&i); cout << *a << endl; 上のプログラムは一応5は表示されたものの その後アサーションがでて終了します そこで質問ですが、auto_ptrは通常の変数やクラス変数を指すと あぼーんするからやっちゃダメなのか、という点です 上のプログラムでアサーションに引っかかるのは a.reset(&i); この時点でiのメモリが開放され 関数終了時に再びiのメモリを開放しようとしてエラー なのだと推測してます
737 :
デフォルトの名無しさん :2006/10/05(木) 19:39:00
自動変数を auto_ptr で管理しようとするのは間違い。
739 :
735 :2006/10/05(木) 19:55:02
そ、そんなのでいいのか… なんか拍子抜けした。
740 :
732 :2006/10/05(木) 20:00:12
>>737 もやもやがすっきりしました、感謝です
shared_ptrでも試してみたけど、ダメでした
ヒープにメモリ領域を作るやつじゃないと
うまくいかないようですね
>>739 分かってると思うけど一応、STLのコンテナで連続性が保証されているのはvectorだけ。
>>740 >Template auto_ptr stores a pointer to an object obtained via new and deletes that object when it itself is destroyed
743 :
732 :2006/10/05(木) 20:18:36
>>742 ありがとうございます
new/deleteのみってことですね
/*
ところで、そのままその文章で検索すると
1998年版のC++最終ドラフトに行きました
HTML形式でWEBに落ちているのも驚いたのですが
それよりも、どうやって短期間で
そういう情報を見つけるか、のほうが気になります
*/
shared_ptrは削除子を指定できるから、何もしない関数を削除子として指定してやれば、 自動変数へのポインタ数をshared_ptrに入れることは可能だと思う。 しかし、そうまでして何がやりたいのか疑問。
745 :
735 :2006/10/05(木) 23:18:30
>>743 ここにいる連中は STL マニアなので、全部暗記してるみたいですよ。
知識そのものと同じかそれ以上に、 知識への正確なポインタを持つことが大事な時代。
なので全て「ググれ」で終わってしまって会話が弾まない。 なんて時代だ。
最近のレスでググるように言われているのは
>>724 くらいみたいだが…
もしかして、それは自分の質問には全てググれと返されるという事実に基づくものですかね?
いやまさかそんな。
一応、置いておきますね。 ,.-─ ─-、─-、 , イ)ィ -─ ──- 、ミヽ ノ /,.-‐'"´ `ヾj ii / Λ ,イ// ^ヽj(二フ'"´ ̄`ヾ、ノイ{ ノ/,/ミ三ニヲ´ ゙、ノi! {V /ミ三二,イ , -─ Yソ レ'/三二彡イ .:ィこラ ;:こラ j{ V;;;::. ;ヲヾ!V ー '′ i ー ' ソ Vニミ( 入 、 r j ,′ ヾミ、`ゝ ` ー--‐'ゞニ<‐-イ ヽ ヽ -''ニニ‐ / | `、 ⌒ ,/ | > ---- r‐'´ ヽ_ | ヽ _ _ 」 ググレカス [ gugurecus ] (西暦一世紀前半〜没年不明)
プログラマ以上に日夜ググってる人々はあまり多くないと思うのだが、この話題もモウいいか
753 :
デフォルトの名無しさん :2006/10/06(金) 19:27:12
ググった関数の数はもう数えられない
>>751 ググレクスだろ、ラテン語も読めないのか
コピペにキレてるバカがいる
無教養を晒されて恥ずかしいんだろう
ラテン語など読めない
C++やってれば自然と英語が強くなるな 今じゃ、CNETのBuzz Out Loud を毎日通勤時間に聞いている
SFINAEとかCRTPとかADLとか boostとか英語読めないとツライな だから俺はツライんだけども
STLのremove_ifで質問があります。 STLのfunctionalやalgorithmを使い始めたばかりでいくつか不明な点が・・・ 以下のような単純なコードがあります vector<int>int_array; for ( vector<int>::iterator it = int_array.begin(); it != int_array.end(); it++ ) { if ( *it == 5 ) { int_array.erase(it); } } 以下につづきます。
つづき これをremove_ifにすると remove_if(int_array.begin(), int_array.end(), bind2nd(equal_to<int>(), 5)); などとすれば同等の処理になるとおもわれますが、 これらにおいて vector<T>に相当するTを classHOGE { public: intm_nullpo0; intgetNullpo0(void) const{ return ( m_nullpo0 ); } }; つづき
つづき vector<HOGE> におきかえて if ( *it == 5 ) { int_array.erase(it); } の部分を if ( it->m_nullpo0 == 5 ) { int_array.erase(it); } もしくは if ( it->getNullpo0() == 5 ) { int_array.erase(it); } とした場合 どのようにremove_ifに当てはめればよいのでしょうか? 構造体、クラスのメンバにアクセスして内部とのifをとる場合のうまいやり方がおもいつきません。 既存の関数オブジェクトだけで解決できるのでしょうか?
一気に貼り付けてTABが全部死んでいることにきがついた・・・orz
struct hoge_equals : std::unary_function<Hoge, bool> { hoge_equals( int i ) : op(i) {} bool operator () ( const HOGE & h ) const { return h.m_nullpo == op; } private: int op; }; std::remove_if( begin, end, hoge_equals( 5 ) );
>>763 標準だけでは無理。専用のファンクタを作るか、boost::bindを使う。
int_array.erase(
std::remove_if(
int_array.begin(),
int_array.end(),
boost::bind(
std::equal_to<int>(),
boost::bind(&HOGE::getNullpo0, _1),
5
)
),
int_array.end()
);
あとアルゴリズム版removeは操作した後eraseしないと
除去した要素が完全に削除されないので注意。
>>760 のfor文はeraseの使い方が間違っているので一応指摘。
for ( vector<int>::iterator it = int_array.begin(); it != int_array.end(); ) {
if ( *it == 5 ) {
it = int_array.erase(it);
}else{
it++;
}
}
また、初心者かあ >711 を思い出してたよ
769 :
760 :2006/10/07(土) 02:16:02
ありがとう、だいたいわかりました。 764で記載してくれたように、struct、classあたりを外で定義する方法自体は わかっていたのですが、classメンバと単純比較するという処理だけのためにしては ちょっと、おおぎょうな仕掛けというか、準備になってしまうなぁ、と思っていました。 ただ、同じようにループまわして、内部のメンバと単純比較という構造が増えてきたので どうにか簡略化できないかなという経緯で上のような状態になりました。 boostはregex,serialize,lexcal_castあたりしかつかってないのでbindについては調べてみます。
770 :
760 :2006/10/07(土) 02:32:22
bindしらべてみました。 便利ですね。引数指定がperlみたいですがw
ちなみにremove系は要素を実際には削除しないよ
つーことは remove だけでは要素のデストラクタも 当然ながら呼び出されることはないわけか。
その通り。命名がおかしいよな(笑)
「移す」という意味だから合ってるのでは?
remove vt. 移す ((from, to)); 片づける; 除去する ((from)); 〔話〕 殺す; 脱ぐ, はずす; 解任[職]する, 退学させる ((from)). vi. 移る, 引越す, 去る ((from, to)).
片付けるの意味かな
ちゃうやろ。 他の場所に移動するんだよ。だからデストラクタを呼ばない。
誰もそんなこと言ってない
片づけるの意味が関東と関西で違う悪寒…
意味的にはあっててもやっぱ削除だと思う人は多い気がする。普通は削除の意味で使われる単語だし。rmとかさ。 俺も悪い命名だとは思うかな。
rmがな。
英語圏の人にはどう思われてるんだろ
remove って名前は確かに変だけど、かといって動作の内容を的確に言い表すのも難しい罠 「不要でない要素をコンテナの手前に寄せる」という動作を一言でズバっと言い表せればいいんだけどなあ
元々英単語removeのイメージは「他の場所へ移動する」だから意味は合ってる。 もっと端的に言うならput_aside辺りだろうね。
BCC5.6.4までは、std::removeと書いたらコンパイル出来ず、_STL::removeと 書く必要があった。 STLportの導入にどうも失敗していたらしく、Cの標準関数remove()だけしか 認識せず、関数の多重定義解決をしてくれなかった。 BCC5.8.0〜は直っている。というかdinkumwareになったから根本的に変わっ ただけだろうけど。
dinkumwareのコードを眺めてると眩暈がしてきます。 あれ、わざと難読化してんのかな? いや、別に眺める必要自体はほとんどないんだけどさ。
コードジェネレーターでも使ってるんじゃね?
>>788 あのさ、 put_aside(...); って書いてるコードを初めて見たとして、何やってるか想像できると思う?
意味も曖昧だしはっきり言って最悪の名前だと思うんだけど。
remove() だってプログラミング畑の人間は普通「削除する・除去する」を想像する。
その想像と実際の動作が異なるから Effective STL でも取り上げられたりしてるんだろう?
仮に「他の場所に移動する」っていう意味を思いついたとしても、
その意味から remove の動作を想像するのは無理があるだろうし。
パッと見て何をするかが想像できなきゃ名前付けとしてまずいだろうよ。
だからこそ名前付けは難しいんだが。
>>792 >プログラミング畑の人間は普通「削除する・除去する」を想像する。
そう一般化されてもなあ。
俺はプログラミング畑の人間だが、remove で「片付ける」を第一に
イメージするので、現在の命名で特に不満は無いけど。
>>792 >パッと見て何をするかが想像できなきゃ名前付けとしてまずいだろうよ
こういうこと言ってる馬鹿に、
「じゃあ、代わりの案出してよ」というと何故か黙りこくるんだよね。
不満だ不満だと喚くけど、それを解消しようとはしない糞。
都合の悪い批評を拒絶する言い訳の中では、一番「もっともらしい」ですよね。 お前の意見には代替案が無い→だから俺はお前の批評なんか受け付けない、っていうのは。
おねがいです、それそうな話は無視してください
あ、それそれ♪
あ、よいよい♪ ちょいなちょいな♪ これだからマはジョークが下手糞だと言われるんだ。 嘘だと思うなら対案出してくれ。
>>795 はぁ?バカかお前。
「だから俺はお前の批評なんか受け付けない」
なんて言ってないだろ。
なるほどなるほど、名前が悪いというんだね。
じゃあこれより良い代わりの案出してよ。って言ってるだけ。
代わりの案出してよってのを拒絶する言い訳の中では、
お前の糞発言が一番「もっともらしい」よなバーカ。
remove より良い名前は思いつかないんだよな この名前は仕方ないんじゃない? put_aside は意味不明だな
>>799 > なるほどなるほど、名前が悪いというんだね。
> じゃあこれより良い代わりの案出してよ。って言ってるだけ。
名前が悪いと言っている人間は「馬鹿」で、代わりの案が出ていないから「糞」なんでしょ?
「って言ってるだけ」じゃないじゃん全然。もう徹底的な人格否定、発言否定。
「じゃあこれより良い代わりの案出してよ。って言ってるだけ。」
これはちょっと笑える開き直りだな。日下部以下。
>>801 本当にバカだなぁお前は。
「代わりの案が出せないから」バカでクソなんだよ。
代わりの案が出せないなら、「名前が悪い」に説得力がないだろ。
それ以上の名前が無いなら、つまりはそれがbest、良い名前ってこった。
結局出せないの?バカでクソ君。
日下部以下って何?意味不明だな。
list::remove とアルゴリズムのremoveは同じ名前で動作が違う。 アルゴリズムのremoveの命名が悪いとは思わないが、整合性がとれてないのはいかんね。
「ベストではないが現状で我慢せざるを得ない」 という状況を経験したことがないのかねぇ 対案がなければ批判できないですかそうですか
ワラ 帽子は脱いでください=Remove your hat, please.
>>805 >「ベストではないが現状で我慢せざるを得ない」
>という状況を経験したことがないのかねぇ
経験があるならガマンしてろよバカ。
>対案がなければ批判できないですかそうですか
対案が無いなら、そもそも批判にすらなってない、だな。
現状がベストなんだから。
「ベストじゃない」ってんなら、最低限なんらかの対案出してからな。
対案を示さない批判ってのは、 よりよい案がありそうだ、という指摘だろ。 根拠として具体的な案を示す必要はないと思うが。
おまいら…… ここはマ板じゃないんだから、もっと技術的に議論しなさい。 とりあえずまとめておいてあげよう。 問題点:std::removeは“remove”の単語の意味から挙動を誤解されやすい -> 解決(案) ・現状のままで、より周知徹底を図る ->現在はこの状況(プロツールを目指すC++らしい解) ・別の名前をつける -> 良い候補なし
おまいら、良い名前が付けられない時は設計が良くないんだよ。
812 :
811 :2006/10/08(日) 14:47:37
根拠は無いけどね
要はこんな議論が起こらないように慎重に名前を付けようってこった。 そして、そう上手くいくわけでもないってこと。 頭に血をのぼらせないで、良い教訓にすればいいのさ。
オブジェクトをmoveして組み上げたコンテナをまたre動かすmoveじゃなくて? syntax sugar を「構文糖」と言ってしまうような直訳的危うさを感じる
構文糖衣だよバカ
list::removeの例を見ても、少なくとも慎重に名前が付けられてないってのは分かるな
50代板にム板的スレがあったらこういう話題は多分出ないだろうな、とは思う 標準関数設計者のスタイルの問題と自分のスタイルが合わないからといって 文句を出してる暇でシノニムラッピングすりゃいいだけの話だからな
syntax sugarは「より良い構文」な
そのまんま move_to_end、move_to_back、move_to_rest とかじゃどうだろうか? と、思ったんだけど、remove 対象になった要素の値が保持されてる保証がないから、 これも挙動を正しく表してない。 むしろ「前方に詰める」という動作を表現した方が良さそう? よく分からんけど、shrink_to_erase とか。
removeを「削除する」という意味にとって、 非コピー系アルゴリズムにおいて「要素を削除する」とは 削除されなかった要素を先頭に集めることだ、と理解するのが、 remove_copyやuniqueとの整合性があって良いと思う。
与えられたものを使ってるだけの連中がそんな議論して どうすんだ?決まってるものを決まった通りに使えばいいだろ。
824 :
デフォルトの名無しさん :2006/10/08(日) 22:17:55
日本人は低能知能なのには呆れますね。 私達中華人民はあなたたちの掲示板を拝見して笑ってみてますよ。ではありがとうございました。
もういいって・・
「下手糞な釣りのフリが下手糞」って二重三重につらいね。
>>792 プログラミング畑の人間なら、既存のものに文句があるなら
作り直して普及させろ。
出来ない奴がガタガタ抜かすな。
| \ __ / _ (m) _ピコーン |ミ| / .`´ \ ∧_∧ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ (・∀・∩< #define put_aside remove (つ 丿 \_________ ⊂_ ノ (_)
>>803 日下部というお人が嫌いな人間が、
相手が該当人物を知っているかどうか考えずに、相手を罵倒するつもりで持ち出す文言。
言われた相手が「日下部なる人物を知っている」かつ「日下部が嫌い」でないと意味を為さない。
つまり「無知には通じない」ということだな。 でもそれって普通のことだね。
日下部って何の人?著者? だとしたら本の内容が厨房丸出しだとかそんなの?
糞スレ化が進んでいます
>>831 つまり、知ってるか知らないかわかんないのに貶しの言葉に使った801がバカだってことです。
でもこれも普通に分かることだったね。
836 :
デフォルトの名無しさん :2006/10/09(月) 18:00:00
なんでこんなに必死なんだろう 理屈になってないし
必死なのはお前でしょう・・・
838 :
デフォルトの名無しさん :2006/10/09(月) 18:07:22
え、今度は同一人物妄想? ほんとに必死だな・・・
何いってるんだろうこのバカ・・・ 同一人物妄想してるのは自分自身だろうに・・・ ほんと必死な馬鹿だな・・・
840 :
デフォルトの名無しさん :2006/10/09(月) 18:13:58
意味不明すぎ モニタの前で赤くなったり青くなったりしてるんだろうな
>>840 意味不明というより、「お前が」馬鹿すぎて理解できてないんじゃない?
なんでスレを必死にageてるの?
全力で釣りに噛み付いてると禿げるぞ。言語が言語だけに。
843 :
デフォルトの名無しさん :2006/10/09(月) 18:28:02
「必死にageてる」←これまた意味不明、電波そのもの 必死って言われたから必死って返したいんだろうか、どんなヘボいこじつけであっても
↑うわ >同一人物妄想してるのは自分自身だろうに・・・ >ほんと必死な馬鹿だな・・・ ホントにコレ当たってるよこの馬鹿・・・
845 :
デフォルトの名無しさん :2006/10/09(月) 18:37:09
また電波キタコレ 妄想世界の中で「鋭いボクが何かをズバリ言い当てた」らしい
なんだかんだいって、実際二人でやってるんだろこれ? 当たってるも何もねえよww
>>845 >妄想世界の中で「鋭いボクが何かをズバリ言い当てた」らしい
お前www さっきから自己紹介ばかりだなwww
最初に「妄想世界の中で「鋭いボクが何かをズバリ言い当てた」」気分になってのは
>838ですかwwwww?
打てば響く鐘のよう。こいつは面白いので最後まで。
std::mapの要素へのアクセス速度って、 配列に直接定数でアクセスするのと 等価と考えても良いんでしょうか?
>>849 配列 O(1)
std::map O(NlogN)
std::mapはO(logN)だとオモ。
うん、O(logN)だな。
mapで速度的に満足できるモノしか作ったことがないから hashとか別にいらねーやっていうシアワセな俺が記念カキコ。
ゲーム探索とかで既出盤面を覚えたりしようとするとさすがに響く。
855 :
849 :2006/10/09(月) 19:12:33
レスありがとうございました 数学に疎く敬遠してたlogとか調べてみたりorz 数増えると重くなりそうですね。
>>855 はっきりいってlog Nなんて殆ど重くないです。
むしろ軽い部類に入ります。
logだと、Nが100→10000になっても2→4にしかならないから、要素数の 増加に対しては相当抑えられるという希ガス。
応用の領域を語れない奴が、止まった頭で「実測が基本、実測が基本」と わかりきったことを連呼。 「宿屋に泊まると体力が回復しますぞ!」しか喋らない町人キャラレベルの回答者は要らないよ。
実際は log N の重さよりもデータ構造の複雑さによる定数のほうが大きいんだよね
std::pairで持つfirstの型にもよるね。operator<に時間がかかるようであれば 配列でアクセスするのと比較しにくくなる。O記法だけは使えるけど。
追加や削除が多い場合は stl::map そうでもないときは stl::sort + stl::equal_range の方がいいと聞く
_STLならわかるんだけどな。STLportの。
>>859 あんたに言ったんじゃない。わかりきったことだと思うなら気にしなくていいよ。
866 :
デフォルトの名無しさん :2006/10/10(火) 02:00:24
標準のドラフト(n1905)を読んでいて気づいたんだが、 vectorのreserveって n > max_size() な時にlength_errorを 投げるようになってるのね。 23.2.4.2 vector capacity ... void reserve(size_type n); ... Throws: length_error if n > max_size(). んー… いまいち価値がわからん。reserveならちょっとぐらい重くしてもいいから 安全な方に振るって意図? でも例外発生源が増えるのはいいのかな。 導入の経緯を見つけられなかったのでhelp希望。
868 :
866 :2006/10/10(火) 03:04:02
素で下げ忘れたorz
>>867 一方的に不満てことはない。よかったり悪かったり。
気分的には、「安全装置がゴテゴテ付くのはどうかなー」ってのが第一。
vectorで自分から例外を投げるのはatだけだ(った)が、
atはoperator[]の範囲チェック付き版だから、チェックすんなってときは
operator[]を使えばよかった。でもreserveに付けられると選択の余地がない。
reserve前に自前でサイズチェックするコードは無駄なチェックを強制される。
とはいえ、reserveは頻繁に呼ぶもんじゃないから性能に悪影響はなさそだし
(ありがちに作れば整数引数と定数との比較1回と条件分岐1回が増えるだけ)、
ゆるゆるのプログラムを少しだけ堅くするには多いに役立つとオモ。
ちとわからんのは、reserveが普通に投げうる例外がbad_allocだけだったのが
bad_alloc + length_error に増えることによる影響。どうなんかな。
それから、length_error は stdexcept にあるからfreestanding環境には困るかも。
vectorほしいだけでもstringをリンクされそうだし。
…と自分では思うが、どういう議論の末に導入されたのかと。
1998年版のC++最終ドラフトからあるようだけど
>>868 こんな
#include <vector>
void f(std::vector<char>& v, std::size_t s)
{
v.reserve(s);
}
871 :
870 :2006/10/10(火) 11:57:25
途中で送信しちゃった。
で、
>>870 のコードを gcc でコンパイルしてアセンブリを見たところ、
最適化無しだと length_error 投げてたんだけど、 -O3 だと消えていた。
そんなわけで大して問題にならない、
と思ったんだけど、 max_size() が size_type の最大値になってるのが
最適化の理由で、 vector<char> から vector<int> にしたらしっかり
length_error 投げるコードが残った。ってことであんまり役に立たない話。
最適化でそんなに挙動が変わって大丈夫なのか?
874 :
デフォルトの名無しさん :2006/10/10(火) 12:30:07
りえ子、結婚してくれ 頼む
>>868 サイズのチェックは Allocator::allocate() の仕事だろうから、
確かに reserve() の仕様とする必要は無いね。
同じ場合の考えられる resize() や insert() には記載されてないのも中途半端。
でも、両方ごっちゃにして bad_alloc ってのも、それなりに困ることはありそう。
876 :
デフォルトの名無しさん :2006/10/10(火) 12:38:12
>>866 reserve()でmax_size()を超えることは「失敗」ではなくて「違反」
だからclass length_error:public logic_errorをthrow「しなくてはならない」という話
charのcapacity(numeric_limits<char>::max())は既知で固定だから
char c = 1024; とはしない
vector<T>のcapacity(max_size())もTによって既知で固定だから
reserve(max_size()+n) とはしない
このへんは型の使い方の違反にかかわることだから std::logic_error ツリーが throw される
std::runtime_error ツリーではなくて
>>877 その論理でいくと、 resize() に length_error の記載が無いのは規格の欠陥ってこと?
>>878 関数名や実装からの類推で判断せずに規格書を参照してください…
880 :
866 :2006/10/11(水) 01:26:02
>>869 うをほんとだずっと前からあったのか。どこで勘違いしたんだ…
人騒がせですまん。
>>877 同意。reserve()でmax_size()越えは実行時エラー(runtime_error)ではなく
プログラミングエラー(logic_error)だよね。
ただ、プログラミングエラーを実行時にどの程度検出するのかは、効率と応相談かな。
仕様に「未定義動作」が氾濫してる方がC/C++らしいような気はする。
881 :
878 :2006/10/11(水) 01:26:11
>>879 ???
意味が分からない。
アンカーミス?
ぬるぽ
>>881 std::basic_string::resize は「書き換えのできる固定文字列」の「型」だから
「型」の持ちうる最大「長」値 max_size() にあわせて logic_error を返す
std::deque::resize
std::list::resize
std::vector<T>::resize
std::valarray::resize
は「型」ではなく「コンテナ」だから最大「長」値を持たないので logic_error は適切ではない
関数 max_size() はあるがこれはコンテナに挿入できる要素の最大「数」
>>880 元ネタの「価値」の話に戻ると
logic_error の throw はプログラミングスタイルにかかわらず強制「されなければならない」から
検出を「する or しない」ではなく必ず検出「しなければならない」ものであって
検出したら安全にプログラムを「終わらせなければならない」
とは規格には書いてないけれども
main()の一番最初の文が try 「でなければいけない」ってレベルの話と同じ
ホビイスト的に組むこと「も」できる「規格」だが
ガチガチに固めること「さえ」できない「規格」じゃ話にならんと
思います
よ
じわっと
886 :
デフォルトの名無しさん :2006/10/11(水) 23:10:13
std::multipliesを使って二乗を求める関数オブジェクトを作りたいと思っています。 boostを使って下記のようにする方法は思いついたのですが、STLだけでなんとかする 方法はないでしょうか? boost::bind(std::multiplies<int>(),_1,_1);
struct pow{ int operator ()(int a){ return std::mulitiplies<int>(a, a); } }; STLだけでデキタ!
オメデトウゴザイマス
890 :
886 :2006/10/11(水) 23:27:59
>>887 class/struct/functionを作るのは無しでおながいします…
>>890 ほらよ
union pow{
int operator ()(int a){ return std::multiplies<int>()(a, a); }
};
x*x
>891 鬼才 >892 どこがfunctorなのかと
>>884 string::resize が「型」で vector::resize が「コンテナ」?意味がわからん。
string も vector も「コンテナ」の要件を満たす「型」で、
resize はそれらに対する共通の操作だろ?
>895 そのdupとやらを使った例キボソ
>>894 std::string は文字連鎖
std::vector は情報連鎖
これは規格書に書いてあります
std::string は「文字列として扱われる任意の連鎖」
std::vector は「任意の連鎖」
std::string は「操作できる文字列型」
std::vector は「操作できる型」
※「操作できる文字列型」は「コンテナ」と呼べるか?
std::string は begin() から end() の文字連鎖を hold していない「型」
std::vector は begin() から end() の情報連鎖を hold している「コンテナ」
std::string は std::vector 等の「コンテナ」に義務づけられた container requirements の束縛外です
std::string::resize() と std::vector::resize() は規格書で全く別の実装法が義務付けられています
std::multiplies<int>()(10, 20); これでどう?
>>897 これコンパイル通るぞ。
#include <boost/concept_check.hpp>
#include <string>
using namespace boost;
using namespace std;
int main(){
function_requires<ContainerConcept<string> >();
return 0;
}
>>897 ,899
stringに関する規格書の記載は、ものによっては
「あまり真に受けるべきではない」部類に入ると思う。
sizeとlengthの両方があるとか、てんこ盛りのメンバ関数とか、
いろいろ議論の的になりがち。
>>897 偉そうに無茶苦茶言ってんじゃねーよ。
21.3 -2-
The class template basic_string conforms to the requirements of a Sequence, as specified in (23.1.1). Additionally,
because the iterators supported by basic_string are random access iterators (24.1.5), basic_string conforms to the
the requirements of a Reversible Container, as specified in (23.1).
1998 の規格からずっと書いてあるよ。
やはり頼りになるべきは規格書だな。トンデモ書いてる奴を殴りたい
>>899 Boostは規格ですか?
型から「桁あふれ」する可能性のある(型std::string)::resize() は logic_error を throw します、これは規格書にあります
(コンテナstd::vector)::resize()は規格書の実装要件では「桁あふれ」する性質は持ちません
>>897 basic_string は連鎖要件に「一致」します、
追加として連鎖要件に必要な random_access_iterator を持ちます、
basic_string は reversible container requirements に「一致」します、
と書いてありますが、これは std::stirng に container requirements が
義務付けられて「いない」という内容です
requirements によって直交性を持たせているのが STL ではなかったでしょうか
std::vector::resize() は insert() に丸投げする実装が義務づけられています
<T>::insert(x) は T(x) か operator=(x) どちらかの操作から throw される例外をそのまま伝達する規格です
規格書を読んでください
904 :
903 :2006/10/12(木) 02:27:45
うわレス番読めてねえ俺
>>901 だな。へろへろ
>>903 もちけつ
規格引くならどこ引いたか書いてくれ。引用長いなら項目番号でいいから
906 :
903 :2006/10/12(木) 02:50:01
>>905 モチケツ!(*´Д`)パンネロ!
std::string::resize() throw(std::logic_error) → 21.3.3.6
std::vector::resize() の丸投げっぷり → 23.2.4.2.6
std::vector::insert() のナイススルー → 23.2.4.3.1
腰が痛いっス。
「連鎖」「一致」ってのは JIS の訳語か?うんこだな。
ってことは人に「規格嫁」とか言いながら自分は俺様用語を連発してたのか。困った奴だ。
基地外だな
>>903 とりあえず言っておくが、basic_stringはコンテナだ。
901にあるとおり、basic_stringはSequence(列)の要件に従う。
その列の要件は、コンテナへの追加要件という形で定められており、
X 3014:2003だと23.1.1では、列は(中略)コンテナの一種であるという一文も見られる。
つまり、列であるということは、コンテナでもあるということ。列⊆コンテナ
ここまで書いたところで、903の言う連鎖がSequence・列のことだと気付いた。
>>907 JISだと「列」・「〜を満足する」となっている。
>>911 23.1.1.1 -
連鎖は線形コンテナと「同種の」もの、
ライブラリはこれと「同種の」もの vector, list, deque を提供する、
さらに stack, queue のようなコンテナアダプタを提供する、
と書いてあるようにコンテナと「同一の」ものではありません
23.1.1.4 sequence requirements はコンテナの必要条件です
が
std::string の sequence は同じ単語を使っていますが
「23.1.1.4 sequence requirements」
ではありません
規格書による枝番参照もありません
>>901 は
std::string を sequence requirements に
「見られるような指定に(as specified in)」
「順応させる(conforms)」
という内容であり
必要条件(requirements)からくる「連鎖の実装強制」ではなく「連鎖と直交性を持っている」という言及です
文章も変 読んでいて疲れる
つまり「日本語でOK」でFA?
"conforms to the the requirements (要件を満たす)" の意味が解らない人がいるってことか。 実装強制なんて意味不明なこと書いてるし。要件を満たすかどうかだけが全てであって、 実装なんかどうでもいいんだよ。
また変なのが湧いたな。 C++ 相談室にも漏れてきてるし。
>>917 原文は
conforms to the requirements of a Sequence, as specified in (23.1.1).
ですから
[conforms to]
[the requirements of]
[a Sequence]
[, as specified in (23.1.1).]
と区切るのが通常ではないでしょうか
指摘の位置で区切ると
[of a Sequence]
の意味が通りません
(requirementsではない) a Sequence と (requirementsである) Sequence requirements を混同していませんか
conforms to the requirements of a Sequence, as specified in (23.1.1)
と書いてある、字面が似ている、だからこれは
(23.1.1) Sequence requirement
のことなんだ、という論理展開はいかがなものかと思います
as specified in が直交性を意図していることをご理解下さい
std::vector::resize() はきゃぴりん☆スルー!されていますがいかがお過ごしでしょうか
921 :
913 :2006/10/12(木) 16:10:18
923 :
デフォルトの名無しさん :2006/10/12(木) 16:21:51
>>920 高校生というか大学1年レベルの英語もできないのか・・・
"conforms to the requirements of a Sequence, as specified in (23.1.1). "は、
「23.1.1章で示されている、シーケンスの要件を満たす」と読む。
それ以外の解釈をしたければご自由に。思想の自由は認めます。
でもそれ誰にも通用しないから、ここで語るのは無意味だと思うよ。
>>920 よくまぁこんだけ捻じ曲がった解釈をしたもんんだ。
string がコンテナだったら何か困るのか?
>>884 ,897 あたりのトンデモ理論を守ってるつもりかもしれんが、
はじめから理論が成り立ってないから、安心してゴメンナサイしとけ。
925 :
デフォルトの名無しさん :2006/10/12(木) 16:42:04
926 :
920 :2006/10/12(木) 16:55:06
>>922 誰か知らん奴の手垢やツバキがついて変色した舶来品もどきを買う気にはなれません><
>>923 「Sequence requirements を満たすから std::string はコンテナ」
>>911 と
「std::string をコンテナが持つ Sequence requirement に準拠させる」
>>923 は
全く違います
場当たり的に論拠を使い分けられると返答の一貫性を保つ手間が余計にかかってしまいます
resize…欠陥じゃないってことでいいですね…返答ないし
>>926 > resize…欠陥じゃないってことでいいですね…返答ないし
つーちゃんねるが基準かよw
珍獣の現れたスレはここですか?
ここは英語学習スレじゃないんだがw
>>926 > 誰か知らん奴の手垢やツバキがついて変色した舶来品もどき
オマエモナー
931 :
920 :2006/10/12(木) 17:07:29
>>924 resize() が logic_error を throw するコンテナなど型の原則に反する!(゚Д゚)使う分にはちっとも困らん!
つーか元々 std::vector::resize() が throw しないのは欠陥なんじゃネーノ?とか
フカす奴にふっかけようと思ったのが発端だからなあ
>>925 検索とかでブツ切りにするとそうなんだけども(;´Д`)TPOっつーのか、文脈が違うと思っていたり
mercury と Mercury が別であるのとほんのり似てる…みたいな説明で済めば俺が楽です
定冠詞と大文字の使い分けってそんなに難しいですかね
>>927 うっせハーゲ(゚Д゚)ハゲハゲ
ハゲは
>>903 のケツ三行参照
>>926 は「〜がContainerである」ってどんな意味で使っているの?
Javaならinterface java.util.Collectionを実装しているとか、
class java.awt.Containerを継承している、だけど。
933 :
926 :2006/10/12(木) 17:15:49
>>932 規格書23(2) Containers library summary に記載されているかいないか
です
ぶっちゃけ
ええ
std::string は記載されていません
規格書21 String library として別章になっています
>>933 じゃぁコンテナの要件に合わせて作った自作クラスも
どんなにがんばってもコンテナにはなれないね。
んなわけねーだろ。
>>934 alignment requirements (3.9.1 と 3.9.2)
>>931 > つーか元々 std::vector::resize() が throw しないのは欠陥なんじゃネーノ?とか
> フカす奴にふっかけようと思ったのが発端だからなあ
>>878 のことを言ってるのかもしれないが、そんな主張をしているわけではない。
>>877 の理由で reserve() が length_error を投げるのならば、
同じ理由で resize() も length_error を投げるはずであり、
それが reserve() にだけ明記されているのは規格の欠陥ではないか、という問いかけ。
欠陥でないというのであれば、
>>877 の理由付けは筋が通らないことになる。
>>936 resize() も logic_error も関係ないな。
ここらでいちおう言っておくが、次スレは要らない。
次スレまだあ?
941 :
932 :2006/10/12(木) 17:50:35
>>933 それはかなり特殊な立場で、
今風ならContainer Conceptのconcept checkに合格するかどうか、
C++2003風ならば、container requirementに合致するかどうかですよ。
これがSFINAEに代表されるC++のtype matching/name lookupに合います。
Generic programmingでは、継承/実装などの型の包含関係に
依存しない型の適合性を重視しています。
要するに、C++使いにとってstd::stringはContainerなんですよ。
「規格書23(2) Containers library summary に記載されて」はいないですけど。
942 :
933 :2006/10/12(木) 17:51:51
>>935 それは「コンテナの要件に合わせて作った自作クラス」ですね
どこまでいっても
前田健はいくら整形しても松浦あや本人にはなれません
Java のは継承したらコンテナファミリーに養子として入れるんですかね仕様上
あまり覚えていなくて
>>937 実行前にわかる「違反」の logic_error を
実行するまで「失敗」がわからない resize() で throw するんスか?
えー
943 :
932 :2006/10/12(木) 17:56:33
>>942 C++はそういう言語じゃないんですよ。
944 :
933 :2006/10/12(木) 18:01:21
>>941 sequences of characters に manipulating を直交させたものがコンテナって気はしないス(;´Д`)
Javaの「書き換えができないString」はあれコンテナですかね…
"〜〜〜"というバイト列を「持つ」「コンテナ」ではなくて
"〜〜〜"という「型」
な解釈でいるんですけれども
しかし
夕飯の支度が
呼ばれています
ああ
>>932 は規格書内限定の話だと思っていたし、今までも規格書の話だったし、ここはそういうスレなので
>>933 で規格書について返答してみた、ら
>>935 がスレタイとは違う「自作クラス」の話を混ぜっ返しのように出してきたので
>>942 で混ぜっ返したら
>>943 言語の話になってしまいました
つーか
自作クラスの resize() に logic_error を throw するコードをつける基準として
それがコンテナだから (std::vector::resize()は投げない)、
型だから (std::string::resize()は投げる)、
という考え方を使うのは無理なんですかね…
>>926 金を払うのが嫌なら、JIS X 3014:2003はPDF化されたものが誰でも無料で読める。
http://www.jisc.go.jp/ ここのJIS検索から、規格番号にX3014と入力していけばよい。
しかし、お前がコンテナの基準を933から変えない限り、
C++関係のスレの奴ら(に限らずC++使い一般)とは半永久的に話が合わないぞ。
ところで17.3.1.2では、「要件」について書かれている。
ライブラリは、C++プログラムによって拡張することができる。各箇条は、そのような拡張が可能な場合、
拡張が満足しなければならない要件を規定する。(以下略)
ここから、要件の存在は、そもそも標準ライブラリ以外にも向けて作られていると俺は考えている。
つまり942の「コンテナの要件に合わせて作った自作クラス」というような考え方を俺は受け入れられない。
これは論理の飛躍が過ぎていると自分でも思うけどな。
もしそうなら17なんかに書かない。
stringはコンテナじゃないよ。 これって常識じゃなかったの? チョット前の2chでは常識のように話してる人が沢山いたのに。
そうか? basic_stringはSTLではないよなら同感だが。
stringがSTLでないという意見はよく見るし、それは、ある程度の論理を伴っている。 が、stringがコンテナでないなんて意見は俺も見た覚えがないな。
basic_stringはSTLではない。 STLはコンテナ、アルゴリズム、イテレータから成っている。 したがって、basic_stringはコンテナではない。
basic_string→コンテナ string→not コンテナ
>>952 その論理だとboost::reverce_iteratorはiteratorじゃないんですか?
さっきからくだらないこと言ってる奴は標準コンテナと自作コンテナの区別ぐらいつけろ。
俺定義のSTLなんてどうでもいいよ
STLとかコンテナとか気にせず、 ただ使いこなせればそれでいいとおもうんだが。 知識偏重主義ってうざいよ。
basic_stringをSTLコンテナだと思って使ってると微妙に足りないメンバ関数があっていらついてくる。
今日はどしたんだ?
>>952 別にSTLに含まれていなくても、要件さえ満たしていれば、
コンテナやらイテレータを名乗るのは全く問題ないと俺は思うんだ。
>>961 コンテナやらイテレータを名乗る≠(標準)コンテナや(標準)イテレータである
これを理解して言っているのなら別に構わないんじゃないかな?
ライブラリを自作して公開する時に、これは自作コンテナですとか
イテレータの要件を満たした代物ですなんていうのはめんどくさいしね。
全部自作自演に見える
しかしてここまで俺の自演
965 :
932 :2006/10/13(金) 00:19:45
966 :
932 :2006/10/13(金) 00:20:18
> 要求仕様ベース型のカテゴライズに慣れてください。 < 要求仕様ベースの型のカテゴライズに慣れてください。
散らかっててよくわからんが
>>946 コンテナと型に2分するのがそもそも無理では。(だいたいコンテナだって型だし)
排他関係ではあるまい。
コンテナの要件: "23.1 Container requirements" を満たすものがコンテナであって、
「標準コンテナだけがコンテナ」と考えるのは、
STLとその仲間たちの一番美味しいところを食べ損ねてる気がする。
俺コンテナを標準アルゴリズムに食わせたりするのが完全に合法なのが
いいところじゃん。これを安心して行えるという約束ごとが「コンテナの要件」でそ。
basic_stringはまず文字列ではあるけれど、(文字に対しては)シーケンスコンテナの
要件を満たす。…でいいんじゃ? 文字以外に対してはどうかなーって感じだが。
ついでに、resizeは "23.1.1 Sequences" の要件には入っていない様子。
vector や list や deque や string に付いているのは揃いも揃って
ただのオマケらしい。
規格書もいいが、全体像の類いは「C++の設計と進化」あたりがお勧め。
質問です。 BCC5.82(Dinkumware STL)を使って、std::hash_mapを使おうとしている のですが、STLportと違って、Keyにstd::stringを使うインターフェースが ありません(std::hash<std::string>がない)。 それで、ユーザー定義のハッシュ関数を書いたら、今度は エラー E2451 C:\Program Files\Borland\BDS\4.0\Include\dinkumware\xhash 187: 未定義のシンボル bucket_size(関数 main() ) エラー E2451 C:\Program Files\Borland\BDS\4.0\Include\dinkumware\xhash 188: 未定義のシンボル min_buckets(関数 main() ) エラー E2029 C:\Program Files\Borland\BDS\4.0\Include\dinkumware\hash_map 77: 'std::_Hash<std::_Hmap_traits <std::string,std::string,StringHash,std::allocator<std::pair<const std::string,std::string> >,0> >' はクラスあるいは構造体として宣言済みでなければならない(関数 main() ) などのエラーが出て、コンパイル出来ません。Dinkumwareではhash_mapを 使う事ができないのでしょうか?
ないというかテンプレートです…
テンプレート?常識という事でしょうか?
>>970 templateは型枠なので合う中身を自分で後から書けるというのが売りなわけで
後から書き足したら
>>968 のようなエラーが出たわけなんですが・・・・
Dinkumwareてhash実装してたっけ?
ある。ただしVC++の奴はstdext::で使わないと互換性警告出るが。
boost/multi_array ってresize やpush_backができないんだね。 無理やりするには、サイズがかわるたびに全部コピーしかない?
出来たら意味ないだろ
>>977 なぜ?
std::vector< boost::ublas::vector<float> > vecList;
vecList.push_back(vec);
はよくやるけど
>>978 multi_array は push_back はないが、resize メソッドはある。
multi_array< int, 2 > a( extens[2][3] ); // 2*3 の 2次元配列。
a.resize( extents[3][3] ); // 3*3 の2次元配列に拡張。
multi_array は必ず長方形で拡張する必要がある上に、
reshape なんかで簡単に形を変えることが出来るから、
ネストしたvectorみたいにはいかないよ。
次スレはどうする? 毎度立てる立てないと騒ぐが結局誰かが立ててずるずるとここまでやってきたが。 俺は、当初いらないと言い続けてきたが、 粘り負けした。今はもう存続させていいと思っている。 なんだかんだいって過疎にならず、5スレ目も終わろうとしている。 みんなはどう思う?
どうでもいい。 あったらあったで粘着してスレをウォッチし続けるし、 なくなったらなくなったらで別に気にしない。
立てるべきでない理由は 「STLをC++から分けて考える理由がない」 実際C++相談室でもSTLの話題は扱われている 立てるべき理由は多分ない...よね? まぁ反対しても惰性で立てる奴がいるし好きにすれば?って感じ
いいかげん STL & Template Metaprogrammingは C++の技法として定着したんじゃないの? ということでC++相談室合流に賛成。
立てたところでC++相談室とSTL相談室の両方とも見るだけだけどね
話がどう転んでも立てる奴がいる限り立つだろ。わざわざ議論することもない。
>>980 も言ってるが少なくとも過疎にはなってないわけだし。
確かにSTLはC++の言語体系の一部と考えても差し支えないんだが、 扱う範囲がデカいので、分割でいいんじゃないですかね。 単純に見易さの問題として。
>>988 分割の境界がはっきりしていれば、それで何も問題ないんだけどね。
はっきりしてるっちゃしてるんだけどね。 普通にC++使ってて出てくるSTLの話題はC++スレで、 ちょいと突っ込んだ話題になったら、ないしは最初からSTLの話したけりゃこのスレで、 てなもんで、今までどおりでいいんじゃまいか。
この無意味な談義はスレ埋め目的も含まれてると見たw
「普通に」「ちょいと突っ込んだ」「てなもんで」 曖昧すぎ。
フヒヒ
むしろSTL自体いらない
個人的には、STL と Boost でまとめて「C++ template 総合」にしてくれるのが一番しっくりする。
俺は STL スレと Boost スレは別が嬉しいかな やっぱり標準になってるものと、そうでないものの差は大きいと思う。
同意
両方いらない
欲しい奴が立てる、これ定説。
1000 :
デフォルトの名無しさん :2006/10/14(土) 14:48:31
通りすがりが1000ゲッツ
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。