【C++】STL(Standard ..
369:デフォルトの名無しさん
08/11/08 15:14:42
二重ループのかわりにstd::find_ifを使ってみようぜ!
あと上で言ってる人もいるけどsortするならむしろstd::vectorのかわりにstd::setを使おうぜ
Itemがidをもつぐらいなら用途にあってる可能性高いし
370:デフォルトの名無しさん
08/11/08 15:20:36
VBでもデータ構造を変えれば劇的に速くなるな。
371:デフォルトの名無しさん
08/11/08 15:27:41
>>369
ちょっとよく分かりませんが、勉強してみます。
今はVBのコードをC++にツラツラ置き換える作業だけをやってます。
VBの配列 → std::vector
VBのString → std::string
という置き換えで、今のところこれ以上のSTLの知識はありません。
アルゴリズムを下手に変えると、新たにバグが混入することになるので。
372:デフォルトの名無しさん
08/11/08 15:33:36
VB6と一緒に心中してくれよ。こっちくんな。
373:デフォルトの名無しさん
08/11/08 15:40:28
移植させてもらえるだけでも素晴らしいことだと思わないか。
374:デフォルトの名無しさん
08/11/08 15:44:24
つうか既にバグ混入しててワロタ
>for( i= 1; i< 0xFFFF; i++ ){
375:デフォルトの名無しさん
08/11/08 16:03:45
findを使って作ってみました
enum { N = 600, ID_MAX = 0xffff };
template<typename ID> struct Compare {
Compare(ID i) : m_i(i) {}
template<typename T> bool operator()(T const& i) { return i.id == m_i; }
private:
ID m_i;
};
template<typename ID, typename Container>
ID find_uniq_id(Container const& m) {
typename Container::const_iterator m_end = m.end();
for (ID new_id = 1; new_id <= ID_MAX; ++new_id) {
if (std::find_if(m.begin(), m.end(), Compare<ID>(new_id)) == m_end)
return new_id;
}
throw std::domain_error("new_id must not be beyond ID_MAX");
}
376:375
08/11/08 17:05:13
id_typeとget_idを特殊化することによってより流用できるようにしてみました
参照の参照が怖いのと面倒臭いのが難点だと思いました
template<typename T> struct id_type { typedef typename T::id_t type; };
template<typename T>
typename id_type<T>::type get_id(T const& x) { return x.id; }
template<typename T>
struct Comparator {
typedef typename id_type<T>::type ID;
typedef bool result_type;
Comparator(ID i) : m_i(i) {}
bool operator()(T const& i) const {
return get_id<T>(i) == m_i; }
private:
ID m_i;
};
template<typename ID, typename Container>
ID find_uniq_id(Container const& m) {
typename Container::const_iterator m_end = m.end();
for (ID new_id = 1; new_id <= ID_MAX; ++new_id) {
if (std::find_if(m.begin(), m.end()
, Comparator<typename Container::value_type>(new_id)) == m_end)
return new_id;
}
throw std::domain_error("new_id must not be beyond ID_MAX");
}
377:デフォルトの名無しさん
08/11/08 17:39:34
これはひどい
378:デフォルトの名無しさん
08/11/08 18:08:48
なんというオナニー
379:デフォルトの名無しさん
08/11/09 02:37:20
数値を文字列にするには
ostringstream を使用する方法がメジャー?
380:デフォルトの名無しさん
08/11/09 02:39:59
>>379
たぶん sprintf を使う人のほうが多い。
snprintf が C++ 標準に入ればさらに増えるかもしれない。
結果を string で使うことや安全性を考えれば ostringstream のほうが良いとは思うけど。
381:デフォルトの名無しさん
08/11/09 02:54:15
sprintfはchar確保するの面倒だとおもうけど
利用者が多いのは何か理由があるの?
382:デフォルトの名無しさん
08/11/09 02:55:45
>>381 C からの移行組。
383:デフォルトの名無しさん
08/11/09 03:10:24
Exceptional C++ Style でstringstreamはsprintfに比べて
だいたい10倍くらい遅いと書かれていた。
384:デフォルトの名無しさん
08/11/09 03:30:02
速度的な点もあるけど
printf系というのは非常に多くの言語で(Win32にはAPIもある)用意されていて
細部の違いはともかく、知っている人が多い、使い方を覚えて無駄にならない、
というのもある。
C++だけの世界だけで見れば型安全性の無さ等非難される面も多いし
「C++らしくない」という良くわからない理由で嫌う人も。
また、(よく知らない人に多いが)セキュリティ等の面で問題があると言い張る人も居る。
385:デフォルトの名無しさん
08/11/09 03:54:57
書式の設定がめんどくさい上に、長くなってしまう気がするんだが俺の書き方悪いのかな
386:デフォルトの名無しさん
08/11/09 04:07:58
>>385
stream のことなら、たぶんそんなもん。
そういえば C++0x でもこの点は特に改善されたような話を聞かないな。
boost の io state saver ぐらいは入ってもよさそうなもんだと思うけど。
387:デフォルトの名無しさん
08/11/09 10:57:41
>>379
boost::lexical_cast を使うがよい
結局 stringstream 使ってるんだけどな
388:デフォルトの名無しさん
08/11/09 11:53:14
>>381
char確保しなくてもいいよ。
std::string str;
int a = 123;
str.resize(256,0);
sprintf((char*)str.c_str(), "%d", a);
str = str.substr(0, str.find('\0'));
389:デフォルトの名無しさん
08/11/09 12:04:57
stringにconst_castか…
390:デフォルトの名無しさん
08/11/09 12:06:07
c_strの間違いw
391:デフォルトの名無しさん
08/11/09 12:23:41
>>388
c_str() の戻り値に無理やり書き込んでも反映されるとは限らんよ
っていうかconst外して書き込むなんて無茶苦茶にもほどがある
392:デフォルトの名無しさん
08/11/09 12:24:08
#include <vector>
#include <cstdio>
#include <iostream>
int main(int, char *[])
{
std::vector<char> buf(0xff, 0);
int n=10000;
std::sprintf(&buf.front(), "%d", n);
std::cout << static_cast<const char*>(&buf.front()) << std::endl;
return 0;
}
なるへそ
393:デフォルトの名無しさん
08/11/09 12:27:03
printf系はセキュリティ面で問題あると思ってたが
問題ないの?
394:デフォルトの名無しさん
08/11/09 12:29:46
const外し
か、漢だ!
395:デフォルトの名無しさん
08/11/09 12:30:56
nの型がintでlog10(n)が100や200にもなるアーキテクチャがあれば教えて欲しいものだ
396:デフォルトの名無しさん
08/11/09 12:41:02
string使おうがvector使おうが
スタック上に領域確保してれば
char配列となんら変わらん
397:デフォルトの名無しさん
08/11/09 12:46:24
>>396
大概はそうだが、規格には反するな
398:デフォルトの名無しさん
08/11/09 13:07:49
>>393
使い方の問題。
ユーザー入力をフォーマット文字列に使おうとする大バカと
最大文字数の指定方法を知らないバカがそう言ってるだけ。
399:デフォルトの名無しさん
08/11/09 13:18:32
>>398
具体的に何の関数を言ってるかわからんけど、
すくなくともsprintfはあぶない
400:デフォルトの名無しさん
08/11/09 13:28:49
一般的にやるべきでないとされていることを「だって出来るじゃん」の一言でやってしまう・・・
くせぇーっ! DQN以下の臭いがぷんぷんしやがるぜぇーっ!
401:デフォルトの名無しさん
08/11/09 13:31:44
>>399
具体的にどこが危ないのか教えてよ
「使い方を間違えたら危ない」というレベルの話なら
「listen()を使う全てのプログラムは危ない」というのと同じになっちゃうから
402:デフォルトの名無しさん
08/11/09 13:39:40
>>401
え?最大文字数を指定できないじゃん
それが危険だと思えないならまぁ好きにするといいよ
403:デフォルトの名無しさん
08/11/09 13:42:38
sprintfで100byteのバッファしか取っていないのに、
100文字以上有るかもしれないユーザ入力を与えるとかね。
404:デフォルトの名無しさん
08/11/09 13:44:11
VCのsprintf_s使ってます(^^)
405:デフォルトの名無しさん
08/11/09 13:46:22
ハア?
char buff[100]
sprintf(buff, "%.80s", user_input);
これのどこが危ないって?
406:デフォルトの名無しさん
08/11/09 13:47:28
まさしく>>398の最下行に書いてあるバカが言ってるとしか思えないんですけど。
407:デフォルトの名無しさん
08/11/09 13:48:08
C++ で何で sprintf なんて使ってるのん?
しかも STL スレで・・・。
ostringstream か boost::format を使っとけ。
408:デフォルトの名無しさん
08/11/09 14:00:20
>>405
そういうことを分かって使う分にはいいけど、
実際に使う人間が必ずしも分かっているとは限らないし、
分かっていても、うっかりやってしまう危険性があるよね。
409:デフォルトの名無しさん
08/11/09 14:04:25
つうかそんな単純なケースならいいけど、
色々出力したりロケールが絡むと出力結果の予想がしんどいだろ
410:デフォルトの名無しさん
08/11/09 14:08:01
そんなレベルなら、「vectorで[]は使わないほうが良い。at()を使え。」と同じじゃないの。
特に>>399はわざわざ>>398に対して言ってるんだから
もっとちゃんとした危険性を指摘してくれても良さそうなもんだけど。
そりゃ、切捨て前提という仕様は良くないとか
全部生かすつもりならsnprintfの方が楽だとか言うのはその通りだけど
それとセキュリティ的な問題は全く別だから。
柔軟性だって例えば
std::vecotr<char> buff;
buff.resize(???);
sprintf(&buff[0], "%.*s", buff.size()-1, str);
のような使い方である程度確保できるし。
>>409
「使いやすさ」と「セキュリティ的に問題」は全く別の話なんですけど。
411:デフォルトの名無しさん
08/11/09 14:13:43
>>410
> 「使いやすさ」と「セキュリティ的に問題」は全く別の話なんですけど。
この一行が>>409の話とは全く別の話なのは、そういうジョークなの?
412:デフォルトの名無しさん
08/11/09 14:14:33
ostreamが状態を持ってるのもしんどい
413:デフォルトの名無しさん
08/11/09 14:14:53
あ、別にユーザー文字列をそのまま配列に落とす場合に限らないよ。
そもそも(1箇所での)ユーザー入力なんて、普通は1つなんだから
例えば
sprintf(filename, "file-%.80s%d.dat", input, num);
のような形式でも、充分に最大値は予想できるし。
あ、「intが512bitの環境を考慮すると面倒」というのはその通りか。
414:デフォルトの名無しさん
08/11/09 14:17:55
使い難さが有るということは、ミスり易いってことじゃね?
ミスってもセキュリティ的な問題が出ないライブラリならいいんだけど。
415:デフォルトの名無しさん
08/11/09 14:19:43
いわゆる、バグというものは、ミスることによって起こるんだから。
十分予想出来るとかで大丈夫じゃないか、なんていい方出来るだったら、
世の中の全てのソフトウェアにはバグが無いってことも言えてしまう。
416:409
08/11/09 14:19:58
>>410
いやだから
出力結果の予想が困難→バッファ長の予想が困難
セキュリティ的にあぶなくね?
という話し
気をつけて使え
って話しなら
そうですね
としか言えないけど
みなミスりがちだからsnprintfとかVC++のセキュア関数とか
あるんじゃないの?
417:デフォルトの名無しさん
08/11/09 14:32:40
いやだから
全然>>398への反論になってない。
「使い方を知らないのが問題」なだけでは
「セキュリティ的に問題がある」ということにはならないから。
まあ、416の言いたいことはもっともだし
他にもっと良い選択肢があるならそちらを使うべきなのは確か。
でも残念ながら標準ではない。
ただ、自分が「使い方を知らないバカ」だという自己紹介はもういいよ。
>>398の最下行を無視して>>402と反論するような人が>>399みたいに書くわけだから。
418:デフォルトの名無しさん
08/11/09 14:35:28
あ、それと、「最大値の見積もりを間違える」点についてだけど
別に用意したバッファの95%以上まで使わなければいけない、というような決まりはないから。
多少(例えば末端の'\0'とか)の計算ミスがあっても充分すぎるように見積もって置けばよい。
例えば>>405のようにね。
419:デフォルトの名無しさん
08/11/09 14:37:36
>多少(例えば末端の'\0'とか)の計算ミスがあっても充分すぎるように見積もって置けばよい。
ええええー
420:デフォルトの名無しさん
08/11/09 14:38:20
最大量がきっちり分かってる状況じゃないかそれでいけるのは
421:デフォルトの名無しさん
08/11/09 14:41:24
は?
当然過ぎて困りますが
ユーザー入力の部分の最大量は>>405のように制限して
その上で他の部分の見積もりが多少違っていても大丈夫なように
ということですけど。
422:デフォルトの名無しさん
08/11/09 14:42:37
ユーザー入力の部分の最大値を制限するのは
当然というか大前提だと思っていましたが、皆さんは違うのですか。
認識の違いですね。
423:デフォルトの名無しさん
08/11/09 14:44:22
つまり、%fは使うなってことですね、判ります。
424:デフォルトの名無しさん
08/11/09 14:48:54
あー、sprintfは使い方が難しくセキュリティ的な問題を起こしやすいので使うべきではない。
とすると、
同じように、
使い方が難しくセキュリティ的な問題を起こしやすいものは使うべきではない
ということになりますね。
つまり、
C++をやめましょう、と。
Javaあたりがよろしいでしょうか。
実際、世間の潮流もそういう流れになってますしね。
425:デフォルトの名無しさん
08/11/09 14:49:50
>>423
%.fを使ってください
426:デフォルトの名無しさん
08/11/09 14:52:52
>>425
sprintf(buf, "%10.0f", 1e100);
427:デフォルトの名無しさん
08/11/09 15:02:23
snprintf()なら、
snprintf(s, sizeof(s), …
ってやっとけば安全だけど、
sprintf()は人間が数えないといけないじゃん。
>>405 見たいな単純なやつだったらどっちでもいいってことになるかもしれんけど、
書式が複雑になってくると、ミスる可能性がでてくるよ。
てか単純にsnprintf()のほうが楽ジャン。sprintf()で人間がバッファサイズ数えるなんて非合理。
428:デフォルトの名無しさん
08/11/09 15:04:36
いつまで STL スレで sprintf の話をやってんだよ。
そんな型安全じゃない C の糞遺物なんぞ C++ で使うな。
429:デフォルトの名無しさん
08/11/09 15:05:04
だよな!
430:デフォルトの名無しさん
08/11/09 15:07:32
>>426
printf("%.2u", -1);
の時に必ず2桁に収まると思う人は居ませんね。
これと同様に最大桁数が見積もれる点は変わらないと思いますが。
いや、最大桁数はbit数に依存するので環境依存ですけど。
>>427
だからsnprintfはC++においては非標準だって。
それに「sprintfはセキュリティ的に問題がある」という意味にはならないよ。
「C++はセキュリティ的に問題がある」というのと同様。
431:デフォルトの名無しさん
08/11/09 15:07:47
ところで型安全って何ですか?
432:デフォルトの名無しさん
08/11/09 15:10:57
snprintfってC99からなんだっけ…
0xでは標準になるのかなぁ
433:デフォルトの名無しさん
08/11/09 15:12:10
なりません
434:デフォルトの名無しさん
08/11/09 15:13:40
相変わらず話題の質が下がると賑わうな。
435:デフォルトの名無しさん
08/11/09 15:20:11
>>432
ドラフト N2798 の 17.1 [library.general] p9 より
> This library also makes available the facilities of the C99 standard library,
> suitably adjusted to ensure static type safety.
436:デフォルトの名無しさん
08/11/09 15:23:46
_scprintfで数えたらいい
437:デフォルトの名無しさん
08/11/09 15:28:25
>>430
doubleの最大桁数を常に見込んでバッファを確保するとでも?
%fを使わずに、素直に%gを使えば済むじゃん。
そういう使いこなしを必要とするからsprintf()は難しいと言うなら判るが、
使いこなしてもいないのに語ろうとするな。
438:デフォルトの名無しさん
08/11/09 15:33:24
結論:ostrstream or boost::lexical_cast or boost::format or boost::egg::to_string
439:デフォルトの名無しさん
08/11/09 16:00:48
結論:いままで聞いた話を総合すると、一番スマートなのはこれ。
std::string str;
int a = 123;
str.resize(12);
sprintf_s((char*)str.c_str(), str.size()-1, "%d", a);
str.resize(str.find('\0'));
ストリームとかで中間バッファを使うのはメモリの無駄だし、sprintfの書式指定能力の高さは最強。
440:デフォルトの名無しさん
08/11/09 16:02:21
>>439
その場合だとstr.size()は0が返るよ。
あと規格は大切にね。
441:デフォルトの名無しさん
08/11/09 16:03:16
>>その場合だとstr.size()は0が返るよ。
ごめん勘違いした。
でもその書き方は受け入れられない。
442:デフォルトの名無しさん
08/11/09 16:05:42
c_str()を出力バッファに使う男の人って
443:デフォルトの名無しさん
08/11/09 16:06:48
もはやSTLじゃねーなw
444:デフォルトの名無しさん
08/11/09 16:13:28
vectorを使えばかろうじてSTLに関する話題の範疇に入…らないか
445:デフォルトの名無しさん
08/11/09 16:17:17
>>439
× (char*)str.c_str()
○ &str[0]
あと、せっかくだから sprintf_s() の戻り値使えよ。
446:デフォルトの名無しさん
08/11/09 16:30:07
>>445
規格ではstd::stringのメモリ上の連続性は保証されていない。
std::vectorと混同するな
447:デフォルトの名無しさん
08/11/09 16:33:39
どうせ大丈夫なんだから別に良いじゃん
448:デフォルトの名無しさん
08/11/09 16:35:47
仕事で一緒にならないなら別にいいよ
449:デフォルトの名無しさん
08/11/09 16:38:17
>>446
C++0x で連続性は保証されるようになるし、
現状のどの実装でも連続性は成り立っている。
450:デフォルトの名無しさん
08/11/09 16:41:45
>>446
URLリンク(www.open-std.org)
まぁ現時点で保証が無いというのは確かなんだけどね。
451:デフォルトの名無しさん
08/11/09 17:38:58
size_t count = _sctprintf(_T("%d"), 777) + 1;
std::vector<TCHAR> buffer(count);
_stprintf_s(&buffer[0], count, _T("%d"), 777);
452:デフォルトの名無しさん
08/11/09 17:52:09
TCHAR(笑)
453:デフォルトの名無しさん
08/11/09 18:42:07
>>449
そういう話をしたいのなら実装依存スレへ逝け
454:デフォルトの名無しさん
08/11/09 18:43:16
>>451
そういう話をしたいのなら実装依存スレへ逝け
455:デフォルトの名無しさん
08/11/09 19:54:23
STLのlistを利用したプログラムを実行中、
"list iterators incompatible" という例外が発生しました。これはどういったエラーでしょうか?
開発環境はVisualStudio2005 AcademicEditionです。
456:デフォルトの名無しさん
08/11/09 20:01:13
ソース晒せ
457:デフォルトの名無しさん
08/11/09 20:06:15
transformの使い方に関して質問があります。環境はGCCです。
目的は、stringの中身をすべて小文字に変換したいのです。
#include <string>
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <iostream>
string aa = "AbCdEfG";
transform(aa.begin(),aa.end(),aa.begin(),tolower)
で、aaの中身をすべて小文字に変換できません。
理由はわかりますでしょうか?
458:デフォルトの名無しさん
08/11/09 20:10:50
>>457
とりあえずコンパイルエラーだろ。
エラーの意味がわからんということならエラーメッセージ晒せ。
459:デフォルトの名無しさん
08/11/09 20:14:20
俺の環境では全部小文字になるが・・・。
460:デフォルトの名無しさん
08/11/09 20:20:44
使用したソース
#include <string>
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <iostream>
using namespace std;
int main(){
string aa = "AbCdEfG";
transform(aa.begin(),aa.end(),aa.begin(),tolower);
}
以下がコンパイルエラー
test.cpp: In function 'int main()':
test.cpp:9: error: no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits\
<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> \
> >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unresolved overloaded f\
unction type>)'
よろしくどうぞおねがいします。
461:デフォルトの名無しさん
08/11/09 20:23:26
>456
URLリンク(www.hsjp.net)
本来の拡張子は.hppです。ごちゃごちゃしててすみません。
103行目のupdate_etc()関数が怪しいと思っているのですが…
462:デフォルトの名無しさん
08/11/09 20:24:53
Effective STL に乗ってたネタかな
463:デフォルトの名無しさん
08/11/09 20:32:13
>>457
たぶん、こういう関数オブジェクトを作ってそれを渡せばいいよ。
struct my_tolower : std::unary_function<char, char>
{
char operator ()(char c) const
{
return std::tolower(c);
}
};
464:デフォルトの名無しさん
08/11/09 20:54:01
transform(aa.begin(), aa.end(), aa.begin(), static_cast<int(*)(int)>(tolower));
通った
typeof(aa)::value_type : char
tolower : int(*)(int)
でtolowerをchar(*)(char)と型推論しようとして失敗してる
なので正確にキャストして与えてやればおk?
465:デフォルトの名無しさん
08/11/09 20:57:12
>>461
まずはデバッガのバックトレースを見たりブレークポイントつかったりしてあたりつければいいよ
segvだろうが、unhandled exceptionだろうがどこで発生したか分かるから
466:デフォルトの名無しさん
08/11/09 21:00:18
>>464
>>460の最後の行の中にunresolved overloaded function typeってのがあるでしょ。
C++では、tolowerが多重定義されているのだが、
それではテンプレート引数の型が決定できないということでエラーになる。
だから、>>464のようにキャストが必要になる。>>463みたいに他の方法も考えられる。
467:デフォルトの名無しさん
08/11/09 21:06:27
>>466
>>464
>>460
ありがとうございます。
なるほどよく分かりました!
468:デフォルトの名無しさん
08/11/09 21:21:38
>465
ありがとうございます。とりあえずどこで投げてるのか絞り込んでみます。
ただ、list iterators incompatibleというのがどういう状態を指すのか、よくわからないのです。
469:デフォルトの名無しさん
08/11/09 21:37:51
vcのstlのincludeディレクトリにて"list iterators incompatible"で全文検索するとか
470:デフォルトの名無しさん
08/11/09 22:01:54
>469
そういう方法もあるのですね
listの中を覗いてみます。
ありがとうございます
471:デフォルトの名無しさん
08/11/12 11:38:03
dequeにpush_backで要素を挿入していくのは、予め配列をサイズ決め打ちで宣言して代入していくのより遅いですか?
472:デフォルトの名無しさん
08/11/12 12:13:18
>>471
速度は実測が基本。
一般的に、 push_back() を繰り返す場合、配列要素のメモリ確保回数が増えるので
遅くなる可能性が高くて、それでも push_back() ならコピーコンストラクタが使われるので
要素の型によっては代入に比べて速い可能性もある。
473:デフォルトの名無しさん
08/11/12 20:00:12
気になるけど図るのが面倒臭いなら、reserveしておけば精神的に気が和らぐ。
474:デフォルトの名無しさん
08/11/12 22:12:15
vectorならreserveは必須だと思う
dequeってどうだろう
475:デフォルトの名無しさん
08/11/12 22:21:59
dequeはある一定の長さのブロックが不連続に確保されるそうだから
reserveしたらシステムからメモリを持ってくる時間は稼げるけどvector
と違ってメモリの再配置は起きにくいんだよね
476:デフォルトの名無しさん
08/11/12 23:24:27
それは実装によるんでは。
477:デフォルトの名無しさん
08/11/12 23:32:37
実装によるのはもちろんだが一般的な実装の話ね
478:デフォルトの名無しさん
08/11/13 01:13:27
dequeのpush_backが(償却じゃなくて正真正銘の)定数時間であることは規格で要求されてたはず
だから一概に実装に依るとも言えない
479:デフォルトの名無しさん
08/11/13 07:48:57
dequeはpush_back/push_frontで既存要素のコピーが起こりえないのがありがたい
まあ最初から要素数が判ってるならvector一択だけど
480:デフォルトの名無しさん
08/11/13 20:37:08
STLのことは良く分からないけど、
list,stack,queue,vector,dequeで空のクラスSampleのポインタを、
10万個格納、(1個delete&削除・1個格納)*10万回、
空になるまでdelete&要素削除 してみた。
vectorは予め追加要素の2倍reserve()した。
要素の追加削除はvector,stack以外『古い物から削除』、前から取り出して後ろから追加でやった。
stack、queueはそれぞれコンテナdequeを利用。
list 68.11 秒
vector 20.344 秒
stack 27.5 秒
deque 9.468 秒
queue 9.438 秒
queueが速すぎてワロタ
dequeは操作する方向次第でstackとほぼ同等
queue,stack,dequeはこの場合、実質同じモノだし
queue,stackのコンテナを変えたら悲惨な結果になった
PCが悲鳴を上げたのでこれ以上のテスト回数は勘弁
481:デフォルトの名無しさん
08/11/13 20:41:18
あぁ、次はboost::circular_bufferだ…
482:デフォルトの名無しさん
08/11/13 20:58:12
>481
>480と同条件、上限20万個として計測してみた。
平均5.5秒くらいだった
483:デフォルトの名無しさん
08/11/13 23:21:57
ひょっとしてlistってあんまり使わない方が良い?
484:デフォルトの名無しさん
08/11/13 23:51:07
むしろ連結リストのくせに良い数字が出てると思うがね
485:デフォルトの名無しさん
08/11/14 00:18:06
リンクリストより配列のほうがキャッシュに引っかかりやすいからいいぞってMSも言いている。
URLリンク(msdn.microsoft.com)
486:デフォルトの名無しさん
08/11/14 00:33:54
>>483
状況次第
listのほうが向いてる使い方もあるしね
487:デフォルトの名無しさん
08/11/14 00:54:30
途中(先頭末尾以外)の要素の削除はlistじゃないとやってられんやろー
488:デフォルトの名無しさん
08/11/14 00:55:31
あとリストの連結やリストの分割もあるか
あれ?そんなことできたっけ・・・?
489:デフォルトの名無しさん
08/11/14 01:01:03
とりあえずただデータを突っ込んで置きたい(出し入れ順番とかどうでも良い)場合には、
リストは不向きってことか
490:デフォルトの名無しさん
08/11/14 01:14:52
昔はやたらとリンクリストを使うのがいいとされていたが、
今のご時世でも初心者にリンクリストを教えたがる間抜けが後を絶たない。
普通にstd::vectorを使えるように仕込んでおけば、std::listを使うのも苦労はないだろうに。
491:デフォルトの名無しさん
08/11/14 01:15:39
>>487
途中の削除もdequeは結構速い。
listは削除してもイテレータが無効にならないのが利点かな。
492:1/2
08/11/14 15:46:52
listを使っていてよく分からない事態に遭遇したので質問します。
長くなってしまったので申し訳ありませんが分割投稿します。
環境:VC++2005 / XP
typedef struct globalArray
{
int type;
char name[100];
float variable[5][5];
} globalVar;
typedef struct nodeDat
{
CShaderNode *nodeKind;
globalVar varDat[5]; // 上の構造体(globalVar)
int dataNum;
float power;
} nodeData;
typedef struct _data
{
nodeData mainNode; // 上の構造体(nodeData)
nodeData blendNode; // 上の構造体(nodeData)
nodeData subNode; // 上の構造体(nodeData)
int materialNum;
dxMaterial *matrials[MAX_MATNUMBER];
} dataBlock;
493:2/2
08/11/14 15:47:25
上のような構造体が有りまして、一番下のdataBlockをリストとして扱っているのですが、
dataBlock tmp;
/* 〜 データ作成処理 〜 */
/* 〜 挿入先探索 〜 */
insert(itr,tmp);
とデータを挿入してリストを覗くと途中までしか正しくデータが入っていません。
データ作成過程で"",NULL,0.0fと全て初期値を用いてデータを初期化しているのですが、
data[0]->mainNode.varDat[0].variable
以降のデータが未初期化のまま生成されています。
構造体を入れ子にする前は正しく動いていたのですが、
listを扱う際は構造体を入れ子で扱うとNG等の制約があるのでしょうか。
ご教授お願いいたします。
494:デフォルトの名無しさん
08/11/14 15:53:19
それだけだと推測しかできん
・初期化の部分が不完全か
・未初期化というのが勘違いか
・リスト操作がバグってるか
のいずれかしかないが、心当たりがないなら何か見逃してるんだろう
そのようなNG的制約は無いので大丈夫
495:492
08/11/14 16:04:13
返信ありがとう御座います。
(※(int)はキャストではなく型を説明上明示するために便宜的につけた物です。紛らわしくてすみません。)
例えば仮データ(tmp)で、
(int)materialNumを0で初期化したのがリストのデータでは
(int)materialNumが-33686019になってしまっているので、
>・リスト操作がバグってる
のでしょうかね……
ありがとうございます。制約は無いときいて安心しました。
もう少し追ってみます。
496:492
08/11/14 16:30:43
連投失礼いたします。
色々弄ってみたところ、構造体のメンバの記述順を入れ替えると正確に入るデータと入らないデータが出てきました。
詳しく調べたところ、連結しようとしている構造体は180byteで、リストで正しく入るのは96byteの領域まででした。
数字的にこれって多分仕様ですよねぇ……
497:デフォルトの名無しさん
08/11/14 18:55:54
-33686019ってことは0xfdだろ?
ちゃんとdeep-copyせんと。
498:デフォルトの名無しさん
08/11/14 19:59:55
dataBlock tmpA;
/* 〜 データ作成処理 〜 */
dataBlock tmpB;
tmpB = tmpA;
ってやって、tmpAとtmpBは同じ内容の独立したオブジェクトになる?
499:デフォルトの名無しさん
08/11/14 20:04:28
誰にもわかりません
500:492
08/11/14 21:01:27
返信ありがとう御座います。
>>498さんのを実行してみたところ、同内容の独立したオブジェクトに成りました。
deep-copyなのですが、
/* 〜データ作成処理〜 */
を抜けた後、tmpに全ての値がきちんと入っていることを確認し、
data.insert(itr,tmp);
でインサートを行っているのですがコピーに関してはlist側で処理されている様で、
こちら側からコピー処理を定義することが出来るのでしょうか。
501:デフォルトの名無しさん
08/11/14 21:50:22
>>500
コピー演算子をオーバーロード。
502:デフォルトの名無しさん
08/11/15 00:35:09
その場合はコピーコンストラクタじゃ?
503:492
08/11/15 01:20:38
すみません、何かもう全く関係ないところが原因っぽいです。
構造体のメモリ領域と他のクラスのメモリ領域が被ってる……
504:デフォルトの名無しさん
08/11/15 03:13:32
あるIDを割り当てるクラスを作成しようと思っています
インターフェースとしてはこんなかんじで
class IDAllocator{
uint32_t T AllocID();
void FreeID(uint32_t id);
};
クライアントコードに対して、一意なIDを割り当てるのですが、
IDを使い終わった後は返却し、後ほど再利用できる様にしたいです。
IDを割り当てる際に、現在使われてないIDの内、最小の数値のIDを返す仕様にしたいのですが、
STL的にかっちょいい実装方法を教えてください
今のところ割り当て済みのIDをvectorに記録しておいて、0から1ずつ増やしてvectorに無いIDがあれば
それを使うというどう考えても効率の悪いやり方でやっています
505:デフォルトの名無しさん
08/11/15 03:44:37
使い終わって返却されたIDをpriority_queueに記録し、再利用するときはそこから取り出す
506:デフォルトの名無しさん
08/11/15 03:48:12
priority_queueが空なら新たに生成する→新しいIDは最も大きい数値になる ってことか
507:デフォルトの名無しさん
08/11/15 09:29:56
インテレータの有効性をチェックする方法はない?
何も代入されてないときなど、別の変数でフラグ保持するのは面倒だと思うので
508:デフォルトの名無しさん
08/11/15 09:59:37
とりあえずend()でも入れとけとか、
有効/無効状態をチェックするなとか、
そもそもインテレータって何とか。
509:デフォルトの名無しさん
08/11/15 14:38:28
そんなあなたにboost::optional
510:デフォルトの名無しさん
08/11/16 01:05:27
>488
splice 使えばできるはず。
511:デフォルトの名無しさん
08/11/16 01:53:37
これっておかしくない?
URLリンク(www.geocities.jp)
512:デフォルトの名無しさん
08/11/16 01:57:21
>>511
どこがどうおかしいと思うのか書けやカス
513:デフォルトの名無しさん
08/11/16 11:21:20
とりあえずテンプレートクラスはクラステンプレート
514:デフォルトの名無しさん
08/11/16 12:11:13
enumの値か?
515:デフォルトの名無しさん
08/11/16 12:14:51
それは別に間違ってなくね
516:デフォルトの名無しさん
08/11/16 12:16:41
MIRROR_X
517:デフォルトの名無しさん
08/11/16 12:24:52
問題ないだろ
MIRROR_X = SCALE | ROTATE
を意図して書いてあるならな。
518:デフォルトの名無しさん
08/11/16 12:35:10
はー?
519:デフォルトの名無しさん
08/11/16 12:50:45
enum bitset
二大不要物(笑)
520:デフォルトの名無しさん
08/11/16 12:54:39
enumを不要とか言うやつは素人
521:デフォルトの名無しさん
08/11/16 13:04:54
enum要らないとか言う奴はただのバカかTMPしない人だろ
522:デフォルトの名無しさん
08/11/16 13:08:23
>C言語であれば、ANDやOR等の演算を使って管理しますが、C++ではbitsetが利用できます。
この辺りで馬鹿を晒している。このサイトも勿論、私のダメサイトリストに載っている。
523:デフォルトの名無しさん
08/11/16 13:10:34
じゃぁbitsetってなんに使うの?
524:デフォルトの名無しさん
08/11/16 13:13:37
ビット単位のフラグの管理をせざるを得ないときに使うかなぁ。ま、そのときが来たら考えるよ。
525:デフォルトの名無しさん
08/11/16 13:16:23
>>522
上級者のあなたがおすすめするサイトを教えてください
526:デフォルトの名無しさん
08/11/16 13:20:55
>>523
>>519
527:522
08/11/16 13:23:15
残念ながら今のところ、初心者に安心してお勧めでキルサイトは見つけていない。
したがって、申し訳ないが期待には応えられない。
ちなみに、私のダメサイトリストは正しくは、「初心者にはお勧めできない(≒ダメ)サイトリスト」だ。
中級者辺りが読む分には、(自力で確認できるノウハウもあるだろうから)まぁ、悪くないかもしれない。
528:デフォルトの名無しさん
08/11/16 13:34:14
enumは型安全じゃないのが気に要らないな
529:デフォルトの名無しさん
08/11/16 13:35:07
C++のenumは、|=するだけでキャストが必要な糞仕様
530:デフォルトの名無しさん
08/11/16 13:44:26
俺は#define派
enumだとアセンブラソースから使えないから
531:デフォルトの名無しさん
08/11/16 13:54:37
>>529
そもそもビットフラグで使うとは限らないわけで…
532:デフォルトの名無しさん
08/11/16 14:08:21
>>519
unionに失礼だろw
533:デフォルトの名無しさん
08/11/16 16:05:41
それは128ビットとかに使うぞ
534:デフォルトの名無しさん
08/11/17 09:37:02
お前らみんな、unionさんに謝れ!
535:デフォルトの名無しさん
08/11/17 15:37:45
アマチュアの俺からすると分からんのだけど、unionって実際の業務で使われてるの?
enumなんかは割りと使ってるんだけど
536:デフォルトの名無しさん
08/11/17 15:48:34
>>535
使うこともあるよ。Cでbitsetもどきを実装するときとか。
537:デフォルトの名無しさん
08/11/17 17:54:37
大きな数値から上位ビットと下位ビット分けたり
538:デフォルトの名無しさん
08/11/17 18:04:00
・建前
unionは環境に激しく依存するから、使わない方がいい。
・本音
いまどきビッグエンディアンとか無いだろw
539:デフォルトの名無しさん
08/11/17 18:11:15
オレも、エンディアン、ビット幅、signedの右シフト、除算の符号は実装決めうちで作ってる
540:デフォルトの名無しさん
08/11/17 18:14:14
>>538
サーバ系では未だにSunが頑張っているから無視できないのよね。
541:デフォルトの名無しさん
08/11/17 18:33:05
うにおんは組み込みCで以前使ってた事がある
おそらく今でも使ってる
542:デフォルトの名無しさん
08/11/17 18:45:55
1の補数はもう絶滅でいいだろ
543:デフォルトの名無しさん
08/11/17 18:50:13
引き算どうすんだよw
544:デフォルトの名無しさん
08/11/17 18:59:06
負数の表現方法のことだろ。
545:デフォルトの名無しさん
08/11/17 19:17:14
それは2の補数
546:デフォルトの名無しさん
08/11/17 19:19:57
Wikipedia項目リンク
547:デフォルトの名無しさん
08/11/17 22:16:38
よその言語だとASCIIにIEEE754も決め打ちと化しているものもあるよな。
548:デフォルトの名無しさん
08/11/17 23:10:13
未だにIBMのサーバでEBCDICとかあるから油断できない
549:デフォルトの名無しさん
08/11/17 23:51:08
>>538
俺はエンディアン入れ替えたいからunion使ってる。
union {
double a;
char b[8];
}
550:デフォルトの名無しさん
08/11/17 23:54:30
つーかネットワークバイトオーダはbigだし
画像処理でもエンディアン入れ替えなんてよくやるでしょ
全部littleで済むと思ってる人ってどういう世界に生きてるんだ?
551:デフォルトの名無しさん
08/11/18 00:08:27
意識する場面なんてほとんどないな
552:デフォルトの名無しさん
08/11/18 00:11:46
>>550
そういうときに、必ずエンディアン変換を挟むコードを書いてしまう(あるいは書かない)
というのがエンディアン決め打ちのコーディングだと思う。
553:デフォルトの名無しさん
08/11/18 00:14:19
#ifdefるだろjk
554:デフォルトの名無しさん
08/11/18 00:41:30
いや、自動判断する。
例えばtiffはヘッダのIかMかで判断できるし、実行環境がどっちなのかはint foo = 0とでもして& fooをchar *にキャストして取り出せば判る。
555:554
08/11/18 00:51:28
s/int foo = 0/int foo = 1/
まぁ、unionは使わないけれど。
556:デフォルトの名無しさん
08/11/18 00:53:15
スレから脱線するが、標準の方法でエンディアンをコンパイル時に知る方法ってある?
実行時ならできるんだが
557:デフォルトの名無しさん
08/11/18 00:58:32
boost/detail/endian.hppとかを見る限り、標準では無さそうだね
558:デフォルトの名無しさん
08/11/18 01:50:26
>>556
コンパイル環境のエンディアンを?
それとも、ターゲット環境?
559:デフォルトの名無しさん
08/11/18 01:58:09
>>556
VxWorksなら_BYTE_ORDERのdefine見れば分かるが他はしらん。
560:デフォルトの名無しさん
08/11/18 13:28:05
>>554
PDP-11位だしな変態なの
561:デフォルトの名無しさん
08/11/18 14:44:19
>>560
お前はSun、IBM、MIPSを敵に回した。
562:デフォルトの名無しさん
08/11/19 16:25:22
vectorについてですが
array.reserve(array.size());
でぴったりのサイズに変わるかと思ったのですが変わりません。
大きなデータを扱ったりする場合、ぴったりのサイズで作り直した方が
メモリが節約できるかと思うのですが、なぜうまくいかないのでしょうか。
何かいい方法はないでしょうか?
563:デフォルトの名無しさん
08/11/19 16:28:10
vector<T>(array).swap(array);
564:デフォルトの名無しさん
08/11/19 16:32:01
reserveは拡大する方向にしか働かないのでは
565:デフォルトの名無しさん
08/11/19 16:36:13
>>>562
§23.2.4.2.2
void reserve(size_type n);
2 Effects: A directive that informs a vector of a planned change in size, so that it can manage the storage
allocation accordingly. After reserve(), capacity() is greater or equal to the argument of
reserve if reallocation happens; and equal to the previous value of capacity() otherwise. Reallocation
happens at this point if and only if the current capacity is less than the argument of reserve().
3 Complexity: It does not change the size of the sequence and takes at most linear time in the size of the
sequence.
greater or qrual と書いてあるから等しいかもしくは大きいとなるので
ぴったりのsize()になる保証はない。
566:デフォルトの名無しさん
08/11/19 16:37:52
おっと
equal to the previous value of capacity() otherwise.
ともあるから、縮小しようとしてもcapacity()は変化しない事になる。
詰まるところ>>563のようにスワップ技法に頼るしかない。
567:562
08/11/20 11:20:10
>>563-566
出来ました。ありがとうございます。
サイズの縮小は出来ないんですね。勉強になりました
568:デフォルトの名無しさん
08/11/21 01:13:58
今までイテレータが指してるコンテナのことをイテランドと呼んでたんですが
そんなの聞いたことないって言われました
ぐぐってもほとんど出てこないので不安になってきたんですが(「イテランド」だとゼロ…)
普通に使いますよね?
569:デフォルトの名無しさん
08/11/21 01:17:07
はつみみです
570:デフォルトの名無しさん
08/11/21 01:18:50
ぐぐった時点で気づいてるだろwwww俺は聞いたこと無いな
iterandにしたら多少出てくるけど、まぁスズメの涙ね
571:デフォルトの名無しさん
08/11/21 01:24:17
あーやっぱり?
iterandは1000件くらい引っかかるから、わざわざカタカナにしないだけで
あっちでは普通の言葉かもしれないと思ってたんですが
じゃあ皆さんはイテレータが指してるコンテナのことはなんて呼んでるんでしょう
「イテレータが指してるコンテナ」ですか?
572:デフォルトの名無しさん
08/11/21 01:24:23
イテレータが指してるコンテナ?
vector<int>::iterator it;
だと
vectorが「イテランド」になんの?
573:デフォルトの名無しさん
08/11/21 01:27:10
例えば
vector<int> v;
vector<int>::iterator it = v.begin();
なら、itはvのイテレータで、vはitのイテランドです
574:デフォルトの名無しさん
08/11/21 01:38:03
iterateeとか言ってみる。
575:デフォルトの名無しさん
08/11/21 03:09:59
Pythonではiterable
576:デフォルトの名無しさん
08/11/21 03:40:26
>>575
それは意味が全然違う
577:デフォルトの名無しさん
08/11/21 03:50:39
iterable はまんまイテレータ(とみなせるもの)。
578:デフォルトの名無しさん
08/11/21 12:37:36
itのコンテナ 程度にしか言わないな
579:デフォルトの名無しさん
08/11/21 12:54:20
イテランドがまあ、何を指している言葉かは
オペレータ⇔オペランド
からの類推でわかるけどさ。
それより世間一般ではイテレータなんだろうが、
俺はついついイタレータと読み書きしてしまう今日この頃。
580:デフォルトの名無しさん
08/11/21 13:15:51
>>579
おいたが過ぎますぞ
581:デフォルトの名無しさん
08/11/21 17:24:11
いてまうどー
582:デフォルトの名無しさん
08/11/21 17:52:19
とりあえず、イテランドがあんまり一般的な言葉じゃないことはよくわかりました
内輪以外では使うのを控えることにします
ありがとうございました
583:デフォルトの名無しさん
08/11/22 02:05:31
あんまりという表現なのか・・・w
584:デフォルトの名無しさん
08/11/22 02:41:16
つうかどこでその言葉を習ったんだろ
585:デフォルトの名無しさん
08/11/22 15:27:41
イテランドでぐぐるとこのスレが引っかかるなw
586:デフォルトの名無しさん
08/11/22 15:47:04
イテランドたんのアニメ化が決定したそうです。
587:デフォルトの名無しさん
08/11/22 16:56:13
とある言語の被反復構造(イテランド)
588:デフォルトの名無しさん
08/11/22 17:09:09
パパ〜遊園地いきたーい
よーし家族みんなでイテランドにでもいくか〜
589:デフォルトの名無しさん
08/11/22 17:16:39
井手ランド
590:デフォルトの名無しさん
08/11/22 17:32:30
とある要素の列挙目録(イテレータ)
591:デフォルトの名無しさん
08/11/22 17:46:29
イテランドたんの要素数は103000ですね、わかります。
592:デフォルトの名無しさん
08/11/22 18:29:32
変数 X が std::list 型で変数 I がその reverse_iterator だとすると
X.erase( I.base() );
で I が示す要素の隣を消去するので I はまだ使えますよね。
VC8 で I を使うと assert で止まるんですけど。
593:デフォルトの名無しさん
08/11/22 18:55:16
その1行だけ示されてもなあ。
594:デフォルトの名無しさん
08/11/22 19:24:06
デバッガで追えばいいじゃん……
595:デフォルトの名無しさん
08/11/22 19:29:51
string strに入っている文字列のi番目から後ろをstr2に代入するにはどうすればいいですか?
596:デフォルトの名無しさん
08/11/22 19:56:15
str2 = str.substr(i);
597:デフォルトの名無しさん
08/11/22 19:57:28
substr
598:デフォルトの名無しさん
08/11/22 20:06:38
>>592
使えない
599:デフォルトの名無しさん
08/11/22 20:25:38
595です。ありがとうございました。あとstringを==で比較するときに小文字と大文字を区別しな方法はありますか?
一度変換しないとだめでしょうか?
600:デフォルトの名無しさん
08/11/22 21:06:58
stringはそもそも「大文字と小文字」っていう概念が無いと思う
601:デフォルトの名無しさん
08/11/22 21:10:43
大文字だの小文字だのは真面目にやり出すと大変だぞ
ロケールの問題とか
602:デフォルトの名無しさん
08/11/22 21:19:34
>>598
std::list の reverse_iterator の場合は1つ後の要素を消去したとき無効になるんですね。
603:デフォルトの名無しさん
08/11/22 21:23:31
stringは複雑なんですね・・・わかりました
604:デフォルトの名無しさん
08/11/22 21:30:16
複雑なのはstringではなく、真の国際化です
605:デフォルトの名無しさん
08/11/22 21:51:06
"ガ"と"ガ"を==で比較してtrueにできないからstd::stringはクソ
606:デフォルトの名無しさん
08/11/22 21:54:04
CLでいうところのequalpを手前で実装しろクソ
607:デフォルトの名無しさん
08/11/22 21:58:17
@と`を同じ文字と解釈するべき環境とかあるからな
608:デフォルトの名無しさん
08/11/22 21:59:34
7bit ASCII内での大文字小文字無視なら、char_traits自作でやる実装を何かの本で見た。
609:デフォルトの名無しさん
08/11/22 22:03:38
typedef pair<double,string> HOGE;
void func(??){
HOGE p;
p.first = data;
p.second = chordname;
pairs.push_back(p);
}
int main(){
deque<HOGE> pairs;
for(){
func();
}
}
mainで作ったdequeにfunc関数で値を入れたいんですがどうしたらいいですか?
もちろんmainのスコープを抜けない限り、dequeが初期化されないようにしたいです。
610:デフォルトの名無しさん
08/11/22 22:04:09
引数
611:デフォルトの名無しさん
08/11/22 22:11:52
引数なのはわかるんですが・・・
void func(deque<HOGE> &pairs){
}
main(){
func(pairs);
}
こうですかね?
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
4776日前に更新/158 KB
担当:undef