【C++】STL(Standard Template Library)相談室 10at TECH
【C++】STL(Standard Template Library)相談室 10 - 暇つぶし2ch1:デフォルトの名無しさん
08/08/26 12:01:17
C++標準ライブラリの一つ、STLについて。

前スレ
【C++】STL(Standard Template Library)相談室 9
スレリンク(tech板)

過去ログ・リンク・書籍紹介は >>2 以降

2:デフォルトの名無しさん
08/08/26 12:02:03
【C++】STL(Standard Template Library)相談室 8
スレリンク(tech板)
【C++】STL(Standard Template Library)相談室 7
スレリンク(tech板)
【C++】STL(Standard Template Library)相談室 6
スレリンク(tech板)
【C++】STL(Standard Template Library)相談室 5
スレリンク(tech板)
【C++】STL(Standard Template Library)相談室 ;4
スレリンク(tech板)
【C++】STL(Standard Template Library)相談室 3
スレリンク(tech板)
【C++】STL(Standard Template Library)相談室 2
スレリンク(tech板)
【C++】STL(Standard Template Library)相談室
スレリンク(tech板)

3:デフォルトの名無しさん
08/08/26 12:03:43
入門ページなど

・入門
URLリンク(www.jah.ne.jp)
・入門,一覧,使い方
URLリンク(www5c.biglobe.ne.jp)
・メソッド一覧
URLリンク(www.wakhok.ac.jp)
・サンプルプログラム集
URLリンク(www.s34.co.jp)
・TIPS集
URLリンク(www.nantekotta.com)
・メルマガ
URLリンク(www.kab-studio.biz)
・解説
URLリンク(ja.wikipedia.org)
URLリンク(www-ise2.ise.eng.osaka-u.ac.jp)

マルチスレッドプログラミングの時には
URLリンク(www.logos.ic.i.u-tokyo.ac.jp)

STLPort
URLリンク(www.sgi.com)
URLリンク(www.stlport.org)

4:デフォルトの名無しさん
08/08/26 12:05:01
書籍紹介


STL標準講座―標準テンプレートライブラリを利用したC++プログラミング
URLリンク(www.amazon.co.jp)

STL―標準テンプレートライブラリによるC++プログラミング 第2版
URLリンク(www.amazon.co.jp)

標準C++:STLの基礎知識
URLリンク(www.amazon.co.jp)

標準講座C++―基礎からSTLを利用したプログラミングまで
URLリンク(www.amazon.co.jp)

STLによるコンポーネントデザイン
URLリンク(www.amazon.co.jp)

Effective STL―STLを効果的に使いこなす50の鉄則
URLリンク(www.amazon.co.jp)

5:デフォルトの名無しさん
08/08/26 12:06:01
C++相談室 part63
スレリンク(tech板)l50
Boost総合スレ part6
スレリンク(tech板)l50
C++0x 4
スレリンク(tech板)l50

6:デフォルトの名無しさん
08/08/27 09:34:44
>>1

7:デフォルトの名無しさん
08/08/29 00:12:00
早速質問です。
set< set< int > > s;
set< set< int > >::iterator i( s.begin() );
i->insert( 12 );

をコンパイルすると、
  error: passing 'const std::set<int, std::less<int>, std::allocator<int> >' as
  'this' argument of 'std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, _Alloc>::const_iterator, bool>
  std::set<_Key, _Compare, _Alloc>::insert(const _Key&) [with _Key = int, _Compare = std::less<int>, _Alloc = std::allocator<int>]' discards qualifiers

と言われる。
これは何が間違ってる?

8:デフォルトの名無しさん
08/08/29 00:37:34
ねぇねぇ。
>>4の書籍紹介にも出てくるSTL標準講座(ハーバーと知るとちょw)なんだけど
これのp.17中段(vectorの代表的なメンバ関数の紹介)に

「end()関数はベクタの最後の要素を指す反復子を返します」

って、書いてあるんだけど、これって間違いだよね?
end()関数は末尾(最後の要素のひとつ後)を指すんだよね?
実際、

vector< int > v( 10, 1 );
vector< int >::const_iterator iter = v.end();
cout << *iter;

みたいにやると、「デリファレンスできねーよ、ばーかばーか」って
実行時エラーがでやがりまくりやがりますりやがりますり。

9:デフォルトの名無しさん
08/08/29 01:01:37
楽しいか?

10:デフォルトの名無しさん
08/08/29 01:04:46
うん。

11:デフォルトの名無しさん
08/08/29 01:11:33
>>8 死にな。

12:デフォルトの名無しさん
08/08/29 01:22:01
死んだら、end()が最後の要素を指す様になりますか?

13:デフォルトの名無しさん
08/08/29 01:22:39
いや、お前が終わるだけ。

14:デフォルトの名無しさん
08/08/29 01:34:36
p.14の
「コンテナ内を巡回するには、 begin() で先頭を指す反復子を取得し、
 反復子の値が end() と等しくなるまで反復子をインクリメントします。」
ってのも、実際にプログラムしたらエラーでる。

つか、気になったのは、シルト先生は for ループの条件に不等号を使うんだよね。
for ( int i = 0, i < 10, ++i )みたいに。
これはAccelerated C++ではやるべきじゃないって最初の方で書かれてる。
なぜなら、普遍の表明を正しく立てられなくなるし、エラーも発見しにくくなるから。
ループの終わりは正確に示すべきで、特に理由がなければ
for ( int i = 0, i != 10. ++i )のように書く方が良い、と。
こうすれば、ループが [0,10) であることを正しく表明できる。

どっちを信じたらいいんだ。

15:デフォルトの名無しさん
08/08/29 01:38:46
俺の個人的な嗜好でいうと、不等号のほうが好きだな。
簡単に要素のスキップとかできるし

16:デフォルトの名無しさん
08/08/29 01:50:51
ランダムアクセスイテレータには < が使えるが、そうでなければ使えない。
!= は任意のイテレータで使用可能である。
従って、後でコンテナの種類を入れ替えたりする可能性があるので!= が無難である。
というのが、STLのイテレータに関する結論。
(コンテナの種類を変更するのは、そんな簡単な仕事じゃなかったりするが。。。)

for 文の本体でカウンタの値を変更出来るのだから、
終了条件 i != 10 がいつも正しい表明とは限らない。

それが正しい表明なら != で書けば良いだろう。
i < 10 でも十分正しい表明であるケースは起こりうる。

ので、int カウンタに対しては、どちらでも良くて、時に応じて好きな方を選ぶ。
ただ、そんな細かい事より、もっと気を配るべき事は沢山ありそうだが。

17:デフォルトの名無しさん
08/08/29 01:58:10
>というのが、STLのイテレータに関する結論。

なるほど。納得。

18:デフォルトの名無しさん
08/08/29 01:59:47
で、結局、.end()はどこを指すのか。

19:デフォルトの名無しさん
08/08/29 02:03:10
末尾であってるよ。

20:デフォルトの名無しさん
08/08/29 03:49:59
>>7
エラーメッセージを見る限り、i.operator ->の戻り値の型がconst set<int>になっているみたい。
これが正しいのか規格のsetのあたりみても分からなかった、すまん。

21:デフォルトの名無しさん
08/08/29 05:25:27
もっと単純な形、例えば以下の2つのコードを考える。

// OK!
set< int > s;
set< int >::iterator iter;
s.insert( 12 );
iter = s.begin();
cout << *iter << endl;

// Error!
set< int > s;
set< int >::iterator iter;
iter = s.begin();
cout << *iter << endl; // ここでError

イテレータ iter はコンテナ s の冒頭を指しているわけだが
コンテナ s が空っぽだから、実際には何も指していない。
何も指していないものはデリファレンスできないのでエラーになる。
当然、存在しないオブジェクトのメソッドも呼び出せない。
なので・・・

set< int > base;
base.insert( 0 );
set< set< int > > s;
s.insert( base );

set< set< int > >::iterator i;
i = s.begin();
i->insert( 12 );

のようにあらかじめなんか突っ込んでおけばOK。

22:デフォルトの名無しさん
08/08/29 06:25:27
>>7,20,21
set の iterator には const が付いてる。
URLリンク(www.open-std.org)

23:デフォルトの名無しさん
08/08/29 10:34:55
キーなんだから、状態が変わるとコンテナが困った事になるわな。

24:デフォルトの名無しさん
08/08/29 22:06:41
vectorやmapの要素にvector<double>やvector<float>を混在させたいのですが、
そういうことは出来ないんですかね?

25:デフォルトの名無しさん
08/08/29 22:15:04
できるお


26:デフォルトの名無しさん
08/08/29 22:19:23
>>25
どうやってやるですかね?
std::vector<std::vector> vec;
vec.push_back(std::vector<float>);
とかだと、vectorのtemplateの型を1行目で指定してないので、
compileがもちろん出来ないんですが。

27:デフォルトの名無しさん
08/08/29 22:30:04
指定すればいいんだよ。

28:デフォルトの名無しさん
08/08/29 22:32:54
>>27
>>26のvecの第一要素はvector<double>で、
第二要素はvector<float>にしたいという意味です。

29:デフォルトの名無しさん
08/08/29 22:35:49
boost使っていいなら
std::vector<boost::any>
とか
std::vector<boost::variant<std::vector<double>, std::vector<float> > >

30:デフォルトの名無しさん
08/08/30 01:08:15
boostすげぇぇぇぇぇぇぇぇぇ!

31:デフォルトの名無しさん
08/08/30 01:31:11
それほどでもない

32:デフォルトの名無しさん
08/08/30 01:49:20
>>31
そうだな
お前が作ったんじゃないもんな

33:デフォルトの名無しさん
08/08/30 01:53:05
>>32
boostさんは謙虚なライブラリで大人気
あまり調子こくとリアルで痛い目を見て病院で栄養食を食べる事になる

34:デフォルトの名無しさん
08/08/30 05:33:14
boostはすごいと思うぜ?
これを知ってるかどうかで生産性が違う

35:デフォルトの名無しさん
08/08/30 09:01:55
いろんな有名な本でもboost位は紹介されるしな

36:デフォルトの名無しさん
08/08/30 09:48:23
一部が次期標準に採用されるくらいだしな

37:デフォルトの名無しさん
08/08/30 10:00:05
progress_displayも次期標準に入るんでしょうか?

38:progress_display
08/08/30 18:19:55
期待して待ってて欲しいお(`・ω・´)

39:デフォルトの名無しさん
08/08/30 21:33:29
progress_displayはC++0xには入りません

40:デフォルトの名無しさん
08/09/02 22:43:24
vectorで2次元配列を作って、任意の行を基準にソートするにはどうしたらいいすか?

41:デフォルトの名無しさん
08/09/02 22:45:46
BOOST_FOREACH

42:デフォルトの名無しさん
08/09/03 11:53:07
ファイル読み込んで、データ整理する際のみソートが1度だけあって
それ以降、そのデータへのアクセスは走査のみの場合

vector と list、Dotch?

43:デフォルトの名無しさん
08/09/03 11:58:40
ランダムアクセスができソートが速いのがvector。
任意の位置への挿入削除が速いのがlist。
よってvectorかと。

44:デフォルトの名無しさん
08/09/03 12:47:33
STLportで_STLP_SHORT_STRING_SZを変更して使用してる人いる?
値を変更しても安全なんかな。

45:デフォルトの名無しさん
08/09/03 18:32:22
コンテナを持つクラスで
コンストラクタ、デストラクタ内でclearするべき?

コンテナ自身、コンストラクタ、デストラクタで
clearは保証されてないんですか?

46:デフォルトの名無しさん
08/09/03 18:33:17
clearしなくていいよ

47:デフォルトの名無しさん
08/09/03 20:19:55
std::vector<union{int, int*}> hoge;
みたいな、要素を共用するようなこと出来ませんか?

unionをtypedefしちゃえばいいんだろうけど、
文を短くできないかなぁと思ったんですが…

48:デフォルトの名無しさん
08/09/03 20:33:20
boost::any

49:デフォルトの名無しさん
08/09/03 20:53:20
boost::variant

50:デフォルトの名無しさん
08/09/03 21:03:49
>>48,49


51:デフォルトの名無しさん
08/09/03 23:23:51
boostがすごすぎて濡れてきた。

52:sage
08/09/20 23:20:38
vector<int> hoge(100);
hoge[0]=41;hoge[1]=10;hoge[2]=20;hoge[3]=2;....
となってるときに、hogeからある決められた数字以下の列だけを先頭から順番に
抜き出したいのですが、一行で書けるでしょうか?
よろしくお願いします。

53:デフォルトの名無しさん
08/09/20 23:26:32
std::transform(hoge.begin(), hoge.end(), to.begin(), std::bind2nd(std::less<int>(), n));

54:デフォルトの名無しさん
08/09/20 23:37:42
copy_ifがあれば簡単なんだが

55:デフォルトの名無しさん
08/09/20 23:38:04
std::remove_copy_if(hoge.begin(), hoge.end(), std::back_inserter(hage), std::not1(std::bind2nd(std::less<int>(), n)));
std::copy_ifでできるよ、と書こうと思ったら無かったorz
C++0xマダー

56:デフォルトの名無しさん
08/09/21 10:20:11
hoge | pstade::oven::filtered(_1 <= boost::lambda::constant(n));

0xで標準になるかもしれないrange baseの<algorithm>, <numeric>が楽しみですね


57:デフォルトの名無しさん
08/09/23 19:57:36
Effective STL第43項を参考に,独自のループをfor_eachを使ったものに書き換えています

つまり,
class Widget {
public:
void redraw() const;
};

list<Widget> lw;

for (list<Widget>::iterator i = lw.begin(); i != lw.end(); ++i) {
i->redraw();
}

上記のようなメンバ関数を呼び出すようなループを下記のように置き換えています。(Effective STLからそのまま引用)

for_each (lw.begin(), lw.end(), mem_fun_ref(&Widget::redraw));


現在悩んでいる問題は
multimap<int, Widget *> widget_map;

for (multimap<int, Widget *>::iterator i = widget_map.begin(); i != widget_map.end(); i++) {
i->second->redraw();
}

このようなmapコンテナに対するループをどうやってfor_eachに置き換えるか…というものです。

for_each (widget_map.begin(), widget_map.end(), .... //これは無理
for_each (widget_map.begin()->second, widget_map.end()->second .... // イテレータでないのでやはり無理

なにか良いアイディアはあるでしょうか?

58:デフォルトの名無しさん
08/09/23 20:10:27
関数を挟めばいいんだよ。
struct MapRedraw
{
void operator ()(std::multimap<int, Widget *>::value_type const& e) const
{
e.second->redraw();
}
};

for_each(widget_map.begin(), widget_map.end(), MapRedraw());

59:57
08/09/23 20:13:42
>>58
なるほど
メンバ関数のみを使うという方法に固執していました

60:デフォルトの名無しさん
08/09/23 20:16:15
スコット・メイヤーズ宣伝乙

61:デフォルトの名無しさん
08/09/23 20:25:17
関数がポコポコ出てくるのがウザい

62:デフォルトの名無しさん
08/09/23 21:07:45
STLを勉強したての頃に抱いた強い期待に比べると、
まったくと言っていいくらい使う機会が無いなぁ、for_eachは。
まぁ、俺はそうだっていう単なるスタイルの話だけれど。

63:デフォルトの名無しさん
08/09/23 21:30:32
0xで無名関数がかけるようになったら、もうちょっとfor_eachの出番も増えるはず。

64:デフォルトの名無しさん
08/09/23 22:02:57
0x厨うぜぇ

65:デフォルトの名無しさん
08/09/23 22:24:07
標準でこれぐらいできるようになって欲しい
for_each(widget_map | map_values | indirected
, bind(&Widget::redraw, _1));

66:デフォルトの名無しさん
08/09/23 22:26:14
>>65
最後のindirectedは要らなくないか?

67:デフォルトの名無しさん
08/09/23 22:44:55
>>65
確かにこの場合だと要らんね、指摘ありがとう

68:デフォルトの名無しさん
08/09/23 22:46:08
訂正
× >>65
>>66


69:デフォルトの名無しさん
08/09/23 22:53:22
lambda使えないとalgorithmって生きてこないんだよね

70:デフォルトの名無しさん
08/09/27 02:47:41
std::vectorを走査する時、
添字よりiteratorのが早いんですか?

71:デフォルトの名無しさん
08/09/27 03:04:51
イテレータがポインタの実装なら、operator[]関数を呼ぶオーバーヘッドの分だけ速いんじゃね。

72:デフォルトの名無しさん
08/09/27 03:05:54
そんなんで変わるほど、コンパイラはへぼじゃない。 判りやすい単純な書き方をするのが一番

73:デフォルトの名無しさん
08/09/27 03:09:19
それは普通最適化で消える。

ただ、一般的な話をすると
vectorはクラス/構造体であり、内部にポインタメンバを持っている。
そのため、[]で参照する時には、必ずメモリ上にベースアドレスを示す変数を読む必要がある。
一方、iteratorはただのポインタであり、レジスタ割付が可能。
そういう意味で、昔の「ポインタ/配列どちらが速い」論争とは意味が違う。

とはいえ、実装と最適化次第なのは当然。

74:デフォルトの名無しさん
08/09/27 13:58:29
・ i < vec.size() より itor != vec.end() の方が実態を正確に表現している
・ algorithm に渡す時はイテレータ
のような理由で、イテレータを使ったほうが、より C++ らしいとはいえるだろう。

75:デフォルトの名無しさん
08/09/27 14:48:13
またit++が遅いから++itにしろの話か

76:デフォルトの名無しさん
08/09/27 14:54:45
>>75
誰に言ってるの。

77:デフォルトの名無しさん
08/09/27 15:06:18
またC++が遅いから++Cにしろの話か

78:デフォルトの名無しさん
08/09/27 20:09:52
またC#が遅いからCにしろの話か

79:デフォルトの名無しさん
08/09/28 12:46:14
環境: VisualStudio 2008

find_ifアルゴリズムを使いたいのですが、
書籍やwebページを参照して

find_if(v.begin(), v.end(), IsTestes);

というふうに記述するとコンパイラがエラーを吐きます。
(IsTestedの行: error C3867: 関数呼び出しには引数リストがありません。
 メンバへのポインタを作成するために & を使用してください)

&を付けて関数ポインタにしても解決しませんでした。
これはVS2008がヘンなの? 俺が何か見落としてる?

80:デフォルトの名無しさん
08/09/28 12:48:44
IsTestes側がまずいと思われ
関数オブジェクトでぐぐるべき

81:デフォルトの名無しさん
08/09/28 13:30:09
>>80
ありがとうございます。
関数オブジェクトに変えたら通りました。

82:デフォルトの名無しさん
08/09/29 13:56:19
>>73
実装の話だが、VC++のChecked Iterator有効状態だとiteratorアクセスが遅く、
vectorの単なる走査だと生ポインタ取り出してインクリメントしたほうが速くなる
結果というのをどっかで見た

83:デフォルトの名無しさん
08/09/29 22:32:49
デバッグ版で速度を気にしても仕方がない

84:デフォルトの名無しさん
08/09/30 00:08:56
>>82
デフォルトで安全なほうに振ってるからな
それ知らずにベンチマークして「遅いwww糞杉www」
って言ってる奴マジ恥ずかしい

85:デフォルトの名無しさん
08/10/03 21:16:07
サンプルコードに下記のコードがあったのですが解説がないので
どのような動きをするのかわかりません・・。
誰か簡単に教えていただけませんか
//------------------------------------------------------------
//STLの補助マクロ
//
//

#define foreach(type,obj,i) \
for(type::iterator i=(obj).begin();(i)!=(obj).end();(i)++)
#define const_foreach(type,obj,i) \
for(type::const_iterator i=(obj).begin();(i)!=(obj).end();(i)++)




86:デフォルトの名無しさん
08/10/03 21:24:03
>>85
解説しろといわれてもこまるほど
簡単なというか基本的なことしかでてきてない
コードなんだがなにが分からないの?
イテレータ知らないの?

87:デフォルトの名無しさん
08/10/03 22:10:28
>>85
typeにはstd::vectorとかのコンテナ型を指定する。objはそのインスタンス。iはイテレータを使ったループ変数だ。
こんな風に使う。

std::vector<int> vecx;
(略).
foreach(std::vector,vecx,i)
{
std::cout<<*i;
}



88:デフォルトの名無しさん
08/10/04 05:58:22
今時のコンピュータ早くて
多少重い部品使っても全然平気。


89:デフォルトの名無しさん
08/10/04 09:28:46
C++でそんなマクロを作る意味あんの?

90:デフォルトの名無しさん
08/10/04 11:03:46
マクロじゃないとできへんのや・・

91:デフォルトの名無しさん
08/10/04 11:42:58
>>85のマクロだけど
「#define foreach(type,obj,i)」のtypeを無くして引数を2個だけにできますか?
何に使うかはともかくとして、ちょっと気になった。

92:デフォルトの名無しさん
08/10/04 11:54:38
>>91
BOOST_FOREACHを使う。


93:デフォルトの名無しさん
08/10/04 12:06:59
BOOST_FOREACHもマクロなんですがw

94:デフォルトの名無しさん
08/10/04 12:19:19
でっていう

95:デフォルトの名無しさん
08/10/04 12:53:53
VC++なら8からfor eachが使える。

96:デフォルトの名無しさん
08/10/04 13:37:59
BOOST_FOR_EACHを使うとループを二重にも三重にも出来る

std::vector<std::vector<int> > vec(10, std::vector<int>(10));
BOOST_FOREACH(std::vector<int>& row, vec)
BOOST_FOREACH(int& i, row)
i = 999;

97:デフォルトの名無しさん
08/10/04 13:44:59
>>91
autoを使う

98:デフォルトの名無しさん
08/10/05 01:30:25
>>97
autoは別スレの話題だ
typeofならギリギリ可

99:デフォルトの名無しさん
08/10/05 15:35:23
vectorへのアクセスを速くする良い方法ってありますか?
いま、
for(vec::iterator it=vec.begin();it!=vec.end();it++) access to *it

for(int i=0, int num=vec.size(), Type *ptr=&vec[0];i<num;i++) accsess to ptr[i];
とかやっちゃってます。

100:デフォルトの名無しさん
08/10/05 15:42:29
>>99
BOOST_FOREACHを使うとend()がキャッシュされる分高速化されるらしい。


101:デフォルトの名無しさん
08/10/05 15:57:14
endをキャッシュするより
>>99のように 数値変数でループ回数を制御する方が速いことが多い

x86のような性能優先のCPUならどっちでも変わらないが
組み込みに使える普通のCPUだと差がつくことが多い

102:99
08/10/05 16:14:17
なるほど、最適化すればx86なら変わらないのですね。ありがとう。

ちなみに、目的としては動的に確保できる多次元配列のアクセスを速く
したいんだけれども。array[][][]と同程度の速度が出たりしますか。
・・・なんて聞いてないで自分で実験してみればいいか^^;

BOOSTはデフォルトでビルドできないためソースを人に渡せないから、
速度の関係ないアルゴリズム検証用にしか使ってません。

103:デフォルトの名無しさん
08/10/05 16:19:22
BOOST_FOREACHはビルドしなくても使える

104:デフォルトの名無しさん
08/10/05 16:27:35
>>103
そうじゃなくてboost入れてない人がいるって話だろ

105:99
08/10/05 16:48:34
そうです。使わない人にとっては、BOOST入れるのって結構面倒ですしね。

ソース書いて、アセンブラ見てみたんだけど、一見したところ変わらないみたい。

通常、静的な多次元配列array[a][b][c]ならば、連続で並んでるのが保障
されてるから、一発で目的のアドレスを参照できるから速い。

疑問なのが、動的な多次元配列の場合、
int ***ptr
ptr = new int**[a]
ptr[i] = new int*[b]
ptr[i][j] = new int[c]
とした時、
ptr[i][j][k]にアクセスすると、ptr[i]にアクセスして、入ってる番地を見
て、更に入ってる番地を・・ってのを繰り返すけど、メモリアクセスは通常
遅いので、動的配列は遅いのだけど。

で、普通に考えてvectorも同じような多重メモリアクセスをやってるような
気がするんだけど、遅くならないのかな。

106:デフォルトの名無しさん
08/10/05 16:56:16
vector<vector<vector<int> > >とかなら105のと同じように遅くなるだろと思う。

107:デフォルトの名無しさん
08/10/05 16:58:03
仕方がない
行毎に列の大きさを変えられる利便性とのトレードオフ

108:99
08/10/05 17:16:38
うーむ、やっぱそうですよね。ありがとうございます。

僕のケースでは大抵の場合は行毎のサイズは固定で、初期化の時から変化
しないって場合が多いので、1次元配列で確保してます。例えば画像デー
タみたいに、ユーザの入力にあわせて初期化サイズが変わるみたいな状況です。

この場合、データの規則性・連続性は保障されるので、構造的には静的多
次元配列と同じパフォーマンスが出せるはずですが、最適化してくれるものですか?

もし可能なら、変数沢山のマクロから解放されてソースも読みやすくなるし、
メモリリークもしないから非常に素敵なんだけどな・・・。

109:デフォルトの名無しさん
08/10/05 17:17:54
長方形や立方体でよければ、1次元に詰め込んでv[i * x + j]とアクセスする方法が取れる。

110:デフォルトの名無しさん
08/10/06 03:44:50
boost::multi_arrayもあるけどインタフェースが変態的なんだよな
結局の所自分で簡単なクラス作って使うのが無難

111:デフォルトの名無しさん
08/10/15 12:18:18
vectorで配列を作って
vectorの要素0から99までの最大値をmax_elementで求める
vectorの要素100から199までの最大値をmax_elementで求める
vectorの要素200から299までの最大値をmax_elementで求める
省略
という処理をしたいんですが、どのようにすればいいでしょうか?

112:デフォルトの名無しさん
08/10/15 12:22:41
a = *max_element(&v[0], &v[100]);
b = *max_element(&v[100], &v[200]);
c = *max_element(&v[200], &v[300]);

113:デフォルトの名無しさん
08/10/15 12:36:31
省略

114:デフォルトの名無しさん
08/10/15 12:37:38
ありがとうございます。
それで出来るはずだと思って試していたら、他の所でミスしてましたorz。
iteratorを使って
ループ文中で
if(count%100){
a=*max_element(iterator,ここが分からない);
}
という風にiteratorを基準に、後ろ100個目までを範囲指定することを出来ませんか?

115:デフォルトの名無しさん
08/10/15 12:41:30
ランダムアクセスイテレータなら
a=*max_element(iterator, iterator + 100);

116:デフォルトの名無しさん
08/10/15 12:42:36
vectorなんだからランダムアクセスできるでしょ

117:デフォルトの名無しさん
08/10/15 12:53:31
出来ました!ありがとうございます!!

118:デフォルトの名無しさん
08/10/19 00:12:46
疑問なんだけど、vectorの配列から作ったiteratorってのは、
ポインタの配列なの?

119:デフォルトの名無しさん
08/10/19 00:21:37
最適化の結果ポインタと同じような動作になるけど
そのものじゃないはず

120:デフォルトの名無しさん
08/10/19 01:13:31
実装によるんじゃなかった?
単にポインタをtypedefしている実装もあれば、classにしてる実装もあるって
聞いたような気がする夢をみたかもしれない

121:デフォルトの名無しさん
08/10/19 16:43:31
vectorの配列から作ったiteratorって言うと、

vector<vector<hoge> >::iterator

のことかい。

122:デフォルトの名無しさん
08/10/19 17:21:14
俺はvector<hoge>[N]のイテレータ、つまりvector<hoge> *のことかと思った
でもどっちにしても話が合わない気がする

123:デフォルトの名無しさん
08/10/19 17:24:23
vi->begin() とか気持ち悪いコード初めて書いたわ

124:デフォルトの名無しさん
08/10/19 17:37:42
別に普通かな

125:デフォルトの名無しさん
08/10/19 18:30:23
ハッシュテーブルの辞書みたいなもんだろ。

126:デフォルトの名無しさん
08/10/19 18:44:13
まったく気持ち悪くないよ

127:118
08/10/20 09:02:02
>>121,122
vector<int>::iteratorみたいなもんです。書き方が悪かったですね。すみません

2Dライブラリだったらピクセルデータの配列を引数
3Dライブラリだったら座標データの配列を引数
にとる関数がありますけど、そういう関数にvectorで管理してるデータを
渡したいときは、どのようにしてますか?
私は、vectorに入ってるデータのサイズ分の配列を作って、そいつに入れてから
ライブラリの関数に渡すってことをしてたんですけど、もっとスマートな方法って
ないですか?

128:デフォルトの名無しさん
08/10/20 09:33:27
vectorのイテレータがポインタだという保証はない
でもvectorの内容がメモリ上で連続している保証はある
だからvがvector<T>なら、Tの配列を要求する関数に&v[0]を渡しても大丈夫
イテレータitに対応するポインタを渡したければ&*itのようにすればいい

129:デフォルトの名無しさん
08/10/20 12:26:11
わかりやすい解答ありがとうございます。
vector便利過ぎる

130:デフォルトの名無しさん
08/10/21 09:58:32
vectorでイテレータなんか使ったこと無いな。
Win32 APIを使う場合は、配列を使わない訳にはいかないから、
何番目という数字が必要な場合が出てくるし、
配列要素アクセスでは、i < vec.size()の記述でないとおかしいから。

131:デフォルトの名無しさん
08/10/21 10:52:18
>>130のイテレータバージョンはたぶんこんな感じだな

vectorでインデックスなんか使ったこと無いな。
algorithmを使う場合は、イテレータを使わない訳にはいかないから、
beginとendが必要な場合が出てくるし、
イテレータアクセスでは、i != vec.end()の記述でないとおかしいから。

132:デフォルトの名無しさん
08/10/21 12:22:45
つか、>>130 が vector で iterator 使ったことがあるかどうかなんて
地球上の誰も興味のない話を唐突にされても。

133:デフォルトの名無しさん
08/10/21 19:53:51
内部でやってることは一緒じゃないの

134:デフォルトの名無しさん
08/10/21 20:01:15
いや、vector のイテレータとか、型が分からないと使えないしめんどいー

インデックスでいいじゃんでも C++ 使うならイテレータつかったほうがいいのかなーどうしよー
と迷うに迷って混在させてgdgdになってる俺みたいな人には重要な話

135:デフォルトの名無しさん
08/10/21 20:26:30
C配列との橋渡し的な役目もあるしね。使う人/使わない人がいるのは当然かと。

136:デフォルトの名無しさん
08/10/21 20:51:16
>>134
対象のvectorが見えてるのに型が判らないってどういう状況だ?

137:デフォルトの名無しさん
08/10/21 21:01:51
いちいちstd::vector<foo>::iteratorと書くのが面倒だと言っているだけだと思う。
早くautoが欲しい。

138:デフォルトの名無しさん
08/10/21 21:04:22
どっちも似たようなものだし、いざとなれば相互に変換できるし、どうでもいい

139:デフォルトの名無しさん
08/10/22 13:30:52
構文糖は重要だよ
各種LL言語が有用性を示してるじゃん

140:デフォルトの名無しさん
08/10/22 13:36:50
イテレータとポインタは構文糖の関係にはない

141:デフォルトの名無しさん
08/10/22 19:03:29
>>137
typedef 一回書けば解決

142:デフォルトの名無しさん
08/10/22 21:04:19
double型 と char型のメンバを持つ構造体をvectorにいれて、全要素入れ終わったらソートみたいにしてるんですけど、

mapとかつかったらもっと効率よくなりますか?ソートするキーはdouble型の値で、降順です。

143:デフォルトの名無しさん
08/10/22 21:30:53
ファイルからや手からの入力ならset使えば、ソート時間はほぼ無い。
読み込んでいる間にソートされるので。
もしメモリ間の転送であっても速いとは思う

144:デフォルトの名無しさん
08/10/22 21:40:54
mapじゃなくてpairかもしれません。

pairでdouble型とchar型のメンバを作って、doubleをキーにソートって感じにしたいんですが、どうしたらいいですか?
char型のメンバは重複する場合もあります。

145:デフォルトの名無しさん
08/10/22 21:46:00
扱う要素数によるよ。
整数とかポインタなら、数千まではvectorの方が一般的に他のコンテナよりも速い

146:デフォルトの名無しさん
08/10/22 21:49:31
つまりvectorにガシガシいれてあとからソートですか?

147:デフォルトの名無しさん
08/10/22 21:50:32
実測しよう

148:デフォルトの名無しさん
08/10/22 21:51:29
それほど速度を気にしないなら、setにぶち込むのが簡単。 いれたらソート終わっているので

149:デフォルトの名無しさん
08/10/22 21:52:15
そんなに速度は気にしません。あまりにも比較して遅いなら別ですが

150:デフォルトの名無しさん
08/10/22 22:02:12
気になるなら測れ、としか。

151:デフォルトの名無しさん
08/10/22 22:03:05
速度気にしてないのか

152:デフォルトの名無しさん
08/10/22 22:13:56
気にしてないわけではありません。
実測してみます

153:デフォルトの名無しさん
08/10/22 22:18:40
typedef struct{

double dist;

char name[20];

}DIST;


int main(){

std::set<DIST> distance;

distance.insert( 200 ); →2要素を代入するにはどうすればいいですか?


}

154:デフォルトの名無しさん
08/10/22 22:22:03
>>153
DIST型のオブジェクトを渡すべきところへ200を渡してどーすんですか

155:デフォルトの名無しさん
08/10/22 22:36:25
あらかじめvectorでサイズを決め打ちするなら早いけど、
領域を増やしていくならsetのほうがはやい

156:デフォルトの名無しさん
08/10/22 22:37:13
>>154
渡し方がわかりません。ソートに使うキーはdoubleのほうです

157:デフォルトの名無しさん
08/10/22 22:40:53
>>153
std::pairでくるんで渡せ

158:デフォルトの名無しさん
08/10/22 22:54:03
こんなんでどう?

struct DIST {
double dist;
char name[20];
DIST(double d, char* str) : dist(d) {
std::strcpy(name, str);
}
friend class Comp;
};

struct Comp {
bool operator()(const DIST& d1, const DIST& d2) const {
return d1.dist < d2.dist;
}
};

int main()
{
std::set<DIST, Comp> distance;
distance.insert(DIST(200, "abc")); //→2要素を代入するにはどうすればいいですか?
distance.insert(DIST(100, "def"));
distance.insert(DIST( 50, "ghi"));

for (std::set<DIST, Comp>::const_iterator pos = distance.begin(); pos != distance.end(); ++pos)
std::cout << pos->dist << ", \"" << pos->name << "\"\n";
}

159:デフォルトの名無しさん
08/10/22 22:54:46
distance.insert( std::pair(200.0 ,"moziretu") );
こうですか?

160:デフォルトの名無しさん
08/10/22 22:56:05
>>158
通りません・・・

161:デフォルトの名無しさん
08/10/22 22:56:51
>>160
これ頭に付けてるよな

#include <iostream>
#include <cstring>
#include <set>

162:デフォルトの名無しさん
08/10/22 23:02:07
>>161
コピペみすってました・・・

struct DIST {
double dist;
char name[20];
DIST(double d, char* str) : dist(d) {
std::strcpy(name, str);
}

friend class Comp;
};

struct Comp {
bool operator()(const DIST& d1, const DIST& d2) const {
return d1.dist < d2.dist;
}
};

これがどういうことをしてるのかわかりません。

163:デフォルトの名無しさん
08/10/22 23:07:19
>>162
まず二要素を一度に代入できるように、DISTにコンストラクタを付けた。
こうする事によって一時オブジェクトが生成できるようになる。

次にソートの基準をdoubleにするために、叙述関数もしくは関数オブジェクト
を書かなければならないが、この場合は関数オブジェクトを書いている。

というのもstd::setのデフォルトの比較基準はless<DIST>となり、これは
存在しないので、自分で書かなければならないからだ。そこで比較関数
オブジェクトにCompを使う事にして自分で書いている。

164:デフォルトの名無しさん
08/10/22 23:09:37
classがstructになっててなんかおかしいよ

165:デフォルトの名無しさん
08/10/22 23:20:44
>>164 わかったよこれでいいだろ
class DIST {
double dist;
char name[20];
public:
DIST(double d, char* str) : dist(d) {
std::strcpy(name, str);
}
double getdist() const {
return dist;
}
const char* getname() const {
return name;
}
friend class Comp;
};
struct Comp {
bool operator()(const DIST& d1, const DIST& d2) const {
return d1.dist < d2.dist;
}
};
int main()
{
std::set<DIST, Comp> distance;

distance.insert(DIST(200, "abc")); //→2要素を代入するにはどうすればいいですか?
distance.insert(DIST(100, "def"));
distance.insert(DIST( 50, "ghi"));

for (std::set<DIST, Comp>::const_iterator pos = distance.begin(); pos != distance.end(); ++pos)
std::cout << pos->getdist() << ", \"" << pos->getname() << "\"\n";
}

166:デフォルトの名無しさん
08/10/23 02:37:33
おまえら暇だな…

DIST dist;
distance.insert(dist);

167:デフォルトの名無しさん
08/10/23 19:19:10
func(string hoge){

}
という関数に

char mozi[256];で宣言された文字列をfunc(mozi)みたいに渡せますか?

168:デフォルトの名無しさん
08/10/23 19:20:02
ええ

169:デフォルトの名無しさん
08/10/23 19:21:30
なんでそんなことができるんですか?

170:デフォルトの名無しさん
08/10/23 19:23:21
stringのコンストラクタにconst char*を取るものがあるから

171:デフォルトの名無しさん
08/10/23 19:26:39
なるほど!STLってほんとにすごいですね

172:デフォルトの名無しさん
08/10/24 00:21:21
でもSTL関係ないですね!

173:デフォルトの名無しさん
08/10/25 03:20:25
stringはSTLだろ
basic_string<char>でテンプレートだし。

174:デフォルトの名無しさん
08/10/25 04:09:49
>>173
馬鹿発見

175:デフォルトの名無しさん
08/10/25 08:24:14
>>173
ん・・あぁ・・そうだね・・・・

176:デフォルトの名無しさん
08/10/25 10:01:54
>>173
const char *を引数にとるコンストラクタを持つ文字列クラスは、STL固有ではありません。

177:デフォルトの名無しさん
08/10/25 17:43:47
んなこたーない

178:デフォルトの名無しさん
08/10/25 18:02:21
自前で似たようなモノを作れるのに?

179:デフォルトの名無しさん
08/10/25 18:47:47
>>176
const T* だよ

>>178
STLであろうがなかろうが全部自前で似たようなものを作れるぞ

180:デフォルトの名無しさん
08/10/25 20:47:06
なんか話が噛み合ってない

181:デフォルトの名無しさん
08/10/25 21:03:12
わかってないんだよ、おそらく本当にw

182:デフォルトの名無しさん
08/10/25 21:23:12
ということにしたいのですね。

183:デフォルトの名無しさん
08/10/25 21:36:55
はいはい模範回答。

もともとのAlexanderのSTLにはbasic_string<>は無かった。
しかし、標準化の過程でSTLコンテナに適合するようにされた。

basic_string<>がalgorithmと重複するようなメンバ関数を持っていたり、
しかもそれがイテレータではなくsize_typeを扱ったりするのはその名残。

184:デフォルトの名無しさん
08/10/27 10:23:42
>>173 の
>basic_string<char>でテンプレートだし。
てのが気になるなあ…
「stream I/O もテンプレートだからSTL」とか言い出しかねない勢い。

185:デフォルトの名無しさん
08/10/27 12:46:36
入念に勉強してない限り、
「C++コンパイラに付いてくるtemplate classを使ったもの全部=STL」
と思っている人は多い気がする
実用上困る事項でもないし・・・

186:デフォルトの名無しさん
08/10/27 15:08:26
定期的に出る話題だから
今回も「ああ、またですか」てなもんだ。
でもbasic_stringはもう
仲間に入れてあげてもいいと思うんだ。

187:デフォルトの名無しさん
08/10/27 16:00:31
やだよ
basic_stringなんてC++標準化委員会も「失敗作だった」と
認めているじゃないか

188:デフォルトの名無しさん
08/10/27 20:21:30
そこまで言ってたっけ。

189:デフォルトの名無しさん
08/10/27 20:55:00
>>186
たまにこのスレを斜め読みするものとしては
そういう話が定期的に回ってくれると
自身の無知加減がよくわかるから助かるよ。

basic_stringって曰くがあったのか・・・(´・ω・)

190:デフォルトの名無しさん
08/10/28 01:35:54
>>187 ソースくれ

191:デフォルトの名無しさん
08/10/28 01:47:14
標準化委員会はSTL自体が「失敗作だった」って
認めてたぞ

192:デフォルトの名無しさん
08/10/28 01:50:21
標準化委員会はC++自体が「失敗作だった」って
認めてたぞ

193:デフォルトの名無しさん
08/10/28 04:45:29
親は>>192自体が「失敗作だった」って
認めてたぞ

194:デフォルトの名無しさん
08/10/28 11:11:11
俺は「性交作だ」って聞いた

195:デフォルトの名無しさん
08/10/28 11:40:21
おあとがよろしいようで

196:デフォルトの名無しさん
08/10/28 20:20:17
100個ぐらいの文字列を入れて
そのなかで一番出現率が高い文字列を探すには
STLのどんなデータ構造とアルゴリズムをつかえばいいでしょうか?

197:デフォルトの名無しさん
08/10/28 20:43:38
まず服を脱ぎます

198:デフォルトの名無しさん
08/10/28 20:44:07
次にソートします

199:デフォルトの名無しさん
08/10/28 20:48:02
かぜひきました

200:デフォルトの名無しさん
08/10/28 20:51:58
相当大変な事態ですね。

201:デフォルトの名無しさん
08/10/28 21:02:46
手術は成功です

202:デフォルトの名無しさん
08/10/28 21:25:40
そーっとしておいてくださいね

203:デフォルトの名無しさん
08/10/28 21:27:19
真面目な解答お願いします

204:デフォルトの名無しさん
08/10/28 21:32:40
std::map<string,int>で出現頻度数えれば?


205:デフォルトの名無しさん
08/10/28 21:36:06
質問です。

struct a {
func() {}
};

struct b {
vector <a> va:
};

とあって、for_eachアルゴリズムでva内のfuncを呼び出すには
どのような書き方をすればいいのでしょうか?mem_fun_refと
bind2ndを組み合わせるのでしょうか?

206:デフォルトの名無しさん
08/10/28 21:44:53
自己解決しました。mem_fun_refだけでいいようです。

207:デフォルトの名無しさん
08/10/28 22:11:52
>>204
連想配列ですよね?stringがキーでintが値ってことですか?

208:デフォルトの名無しさん
08/10/28 22:14:09
hash


209:デフォルトの名無しさん
08/10/28 22:17:42
map<string,int> mとすると、m[str]++としてあとはソートなりなんなりすりゃいい

210:デフォルトの名無しさん
08/10/28 22:30:23

map<string,int> test;

test["hoge"]++;

sort(test.begin(), test.end(), greater<int>());

こうですか?


211:デフォルトの名無しさん
08/10/28 22:40:03
mapってソートできないだろ
挿入した時点でキーで自動的にソートされてるんだから

全部要素を挿入したらvectorにでも全要素をコピーして
今度はint基準でソートすればよい

212:デフォルトの名無しさん
08/10/28 22:41:26
なるほど。どうりでコンパイルが・・・
ちょっとやってみます

213:デフォルトの名無しさん
08/10/28 22:43:39
vectorにキーと値の構造体をコピーするんでしょうか?

最大値を知りたいのではなく、最大値をとるキーをしりたいんです

214:デフォルトの名無しさん
08/10/28 22:51:17
脳味噌を使え脳味噌

215:デフォルトの名無しさん
08/10/28 22:55:46
何か汚ねえなあ・・・lambdaを使わないとやっぱ綺麗に書けんわ

struct Comp : public std::binary_function<std::pair<std::string, int>, std::pair<std::string, int>, bool> {
bool operator()(const std::pair<std::string, int>& v1, const std::pair<std::string, int>& v2) const {
return v1.second < v2.second;
}
};

void print(const std::pair<std::string, int>& v)
{
std::cout << "string = '" << v.first << "', count = " << v.second << std::endl;
}

int main()
{
std::map<std::string, int> msi;
std::vector<std::pair<std::string, int> > vsi;

msi["abc"]++; msi["abc"]++; msi["abc"]++; msi["abc"]++; msi["abc"]++;
msi["def"]++; msi["def"]++;
msi["ghi"]++; msi["ghi"]++; msi["ghi"]++; msi["ghi"]++;

for (std::map<std::string, int>::iterator pos = msi.begin(); pos != msi.end(); ++pos)
vsi.push_back(std::make_pair(pos->first, pos->second));

std::sort(vsi.begin(), vsi.end(), Comp());
std::for_each(vsi.begin(), vsi.end(), print);
}

216:デフォルトの名無しさん
08/10/28 22:58:14
わざわざmapにするいみあんの?

217:デフォルトの名無しさん
08/10/28 22:59:29
なんか複雑ですね・・・
ちょっと解読してみます

218:デフォルトの名無しさん
08/10/28 23:01:17
>>216
挿入が楽
それだけ

219:デフォルトの名無しさん
08/10/28 23:03:53
ああ強いて言えば挿入が速いか・・・

220:デフォルトの名無しさん
08/10/28 23:04:51
「一番」出現頻度高いのが欲しいだけなら、わざわざソートまでする必要なかろ
O(n)で済むぞ


221:デフォルトの名無しさん
08/10/28 23:05:45
>>220
えっとどうするんですか?

222:デフォルトの名無しさん
08/10/28 23:07:06
mapに突っ込んだ後で、単に全舐めすりゃいいだろ
シークエンスの最大値を求めるのにいちいちソートするのか?お前さんは

223:デフォルトの名無しさん
08/10/28 23:09:36
まあそうだな
イテレータを回すだけ
最大値が知りたいだけならそれでいい

224:デフォルトの名無しさん
08/10/28 23:11:33
まあただ最大値の文字列の候補が複数あった時は少々工夫が必要か

225:デフォルトの名無しさん
08/10/28 23:12:10
最大値にタイがある場合も考慮せにゃならんな
単純でいて意外と深いのかもしれないw

226:デフォルトの名無しさん
08/10/28 23:17:42
int main(){

string str;

map<string,int> test;

int maxval=0;
int maxkey;

test["hoge"]++;
test["hoge"]++;
test["huga"]++;

map<string, int>::iterator itr = test.begin();
map<string, int>::iterator itrEnd = test.end();



while(itr != itrEnd){

      itr++;
}


}

こうしたんですが、値自体はどうやって参照するんですか?

227:デフォルトの名無しさん
08/10/28 23:21:00
itr->second

228:デフォルトの名無しさん
08/10/28 23:23:12
ああそうかpairのコンテナなんですよね

229:デフォルトの名無しさん
08/10/28 23:25:51

int main(){

string str;

map<string,int> test;

int maxval=0;
string maxkey='\0';

test["hoge"]++;
test["hoge"]++;
test["huga"]++;

map<string, int>::iterator itr = test.begin();
map<string, int>::iterator itrEnd = test.end();



while(itr != itrEnd){
if(itr->second >maxval){
maxval = itr->second;
maxkey = itr->first;
}
itr++;
}

cout << "maxkey:" << maxkey << endl;

}
コンパイルはできるんですが、とまります・・・

230:デフォルトの名無しさん
08/10/28 23:27:09
>>224-225
そうなんですよね。その辺は工夫でできそうです


231:デフォルトの名無しさん
08/10/28 23:29:41
タイを考慮しても2回舐めればいいだけだから、たいした問題ではないか
なんちって

232:デフォルトの名無しさん
08/10/28 23:30:49
タイがあっても3つ以上はことはないとおもうんで、大丈夫そうです。

しかし動かないです・・・

233:デフォルトの名無しさん
08/10/28 23:34:12
>>229
>string maxkey='\0';

が良くない。これはstring maxkey=NULL; と同じ意味になる。
つまりアドレス0をアクセスする文字列で初期化しようとする。

234:デフォルトの名無しさん
08/10/28 23:35:44
基本からやった方がいいんじゃ・・・

235:デフォルトの名無しさん
08/10/28 23:37:58
>>233
if文内で代入するので問題ないかと思ったんですが・・・

>つまりアドレス0をアクセスする文字列で初期化しようとする。
??

236:デフォルトの名無しさん
08/10/28 23:38:35
微妙に誤解を招きそうなので訂正

×つまりアドレス0をアクセスする文字列で初期化しようとする。
○つまりアドレス0から始まるC文字列で初期化しようとする。

処理系によっては文字列が大きすぎて止まり、他の処理系では
アドレス0をアクセスするのでセグメントエラーで止まったりする。

237:デフォルトの名無しさん
08/10/28 23:39:17
正しくはstring maxkey=""; あるいは単にstring maxkey でいい。

238:デフォルトの名無しさん
08/10/28 23:40:39
>>235
charだけを引数に取るコンストラクタがないため、
暗黙の変換でconst char*を引数に取るコンストラクタが呼ばれてしまう。

239:デフォルトの名無しさん
08/10/28 23:40:40
わかりました。親切にありがとうございました

240:デフォルトの名無しさん
08/10/28 23:51:42
つーか、'\0'はintじゃね?

241:デフォルトの名無しさん
08/10/28 23:55:17
あとまだ質問が・・・

map<string,int> test;

while(){

if(条件){ }


}

として、条件が成立したときだけ、testを初期化(すべてのキーに対して値を0にしたい)したいのですが、どうすればいいですか?

242:デフォルトの名無しさん
08/10/28 23:55:37
>>240
だから、std::string::string(0) が呼ばれてしまう。
この意味をよく考えてみろ。

243:デフォルトの名無しさん
08/10/28 23:59:24
>>241
イテレータを回して全てのsecondに0を代入するしかないだろ

244:デフォルトの名無しさん
08/10/29 00:00:28
if(){

map<string,int> test;


}

ではだめですか?

245:デフォルトの名無しさん
08/10/29 00:04:15
>>244
それはまずい。if文の外側のtestが隠蔽されてしまう。

246:デフォルトの名無しさん
08/10/29 00:08:10
ネタとマジレスの見分けがつかない

247:デフォルトの名無しさん
08/10/29 00:08:27


map<string,int> test;

while(){

if(){

map<string,int> test;


}
}

でもですか?

248:デフォルトの名無しさん
08/10/29 00:10:01
>>247
同じ事だ。
>>246
うむ・・・釣られてるのやもしれぬ

249:デフォルトの名無しさん
08/10/29 00:15:38
決して釣りとかじゃありません。知識不足ですいません。

250:デフォルトの名無しさん
08/10/29 00:19:30
釣りじゃないなら

・差し当たってSTLよりも先にstringの予備知識を付ける
・スコープの意味を理解する

これは最低限やっておく事をお勧めする

251:デフォルトの名無しさん
08/10/29 00:20:28
わかりました!ありがとうございました

252:デフォルトの名無しさん
08/10/29 00:29:30
while(itr != itrEnd){

itr->second = 0;
itr++;
}
初期化はこんな感じですかね?
firstのstringの初期化もいりますか?itr>first="";としたらコンパイルできなかったので・・・

253:デフォルトの名無しさん
08/10/29 00:35:55
itr->firstはconstだろが。
なんでそんなことがしたいんだよ!

254:デフォルトの名無しさん
08/10/29 00:39:00
>>252
お前は一度STL標準講座の本を買ってきてサンプルプログラムを
全部手で打ち込んで走らせて実行してみろ。

俺はそうやって覚えた。

255:デフォルトの名無しさん
08/10/29 00:40:34
252の質問はわすれてください!whileでインクリメントしてたitrをbeginに設定しなおしてなかった・・・

256:デフォルトの名無しさん
08/10/29 04:25:30
学習の初期なら、ヘタすりゃ一日100個はつまらん疑問(後から考えれば)が浮かぶもんだが、
その頻度でいちいち書き込まれちゃかなわん。

ていうか、ある疑問を自力で解こうと動く過程で、副作用的に身につく多くの事柄こそが
実質的には学習のメインだと思うんだが(疑問を1つ解決する度に、幾つもの新知識が身につく)、
いちいち質問してたらその一番大事な効能が激減するぞ。

257:デフォルトの名無しさん
08/10/29 06:08:33
至言

258:デフォルトの名無しさん
08/10/29 07:53:27
つか、STL以前の問題ばかりだな

259:デフォルトの名無しさん
08/10/29 08:05:31
>>240
C では int だけど C++ では char 。

260:240
08/10/29 08:55:46
>>242
あほ。
文字列リテラルに文字を突っ込む馬鹿じゃねーよ。
勝手に他人認定するな

261:デフォルトの名無しさん
08/10/29 10:43:00
考えてみろ、と言われても
何も考えず「あほ」呼ばわりする程度には馬鹿なんですね。

262:デフォルトの名無しさん
08/10/29 12:49:34
>>261は何か勘違いをしてないか

263:デフォルトの名無しさん
08/10/29 13:28:07
あほだし仕方がない

264:デフォルトの名無しさん
08/10/29 17:05:21
>>258
だからあのときあれほどC++相談室とスレ分けるなと言ったのに・・・

265:デフォルトの名無しさん
08/10/29 17:08:29
>>264
一緒にしたら荒れて収拾付かなくならなくないか?
C++相談室が過疎ってるから丁度いいのかもしれんけど

266:デフォルトの名無しさん
08/10/29 21:05:44
初心者スレに行くべきだと思う

267:デフォルトの名無しさん
08/10/30 17:12:36
リストの中身をAの順で並び替えて、A同士が連続したままになるように
Bの順で並び替えるにはどうすればいいの?

268:デフォルトの名無しさん
08/10/30 17:17:32
Bでソートした後
Aで安全ソート
ってことか?

269:デフォルトの名無しさん
08/10/30 17:52:56


>>267

あ1 あ2 あ3 い7 い9 う4 う5 う6
てな感じ?

270:デフォルトの名無しさん
08/10/30 22:02:56
>>268
安全じゃなくて安定だろ

271:デフォルトの名無しさん
08/10/31 00:01:29
stable_sort

272:デフォルトの名無しさん
08/10/31 07:46:27
期待通りの並てになるまでランダムに入れ替える

273:デフォルトの名無しさん
08/10/31 07:54:36
きたいどおりのなみて?

274:デフォルトの名無しさん
08/10/31 08:11:40
>>272
ほんとにそういうアルゴリズムがあるんだよな
最初見たときギャグかと思ったが
URLリンク(ja.wikipedia.org)

275:デフォルトの名無しさん
08/10/31 08:54:38
お前らボゴソートさんをあまりなめない方が良い。

276:デフォルトの名無しさん
08/10/31 08:54:40
勿論、ギャグですが。

277:デフォルトの名無しさん
08/10/31 09:48:11
イテレータを保持して参照しようとするとエラーが出る

erase()はしてない、参照前にpush_back()をした
push_back()すると以前のイテレータが無効になるのか?

278:デフォルトの名無しさん
08/10/31 09:52:06
>>277
無効になるコンテナもある。vectorとかdequeとか。
無効にならないコンテナもある。listとかmapとか。

279:デフォルトの名無しさん
08/10/31 12:25:13
まさにvector
場所を保持できないので必要なデータをとるときに
最初から検索しなきゃならないので不便だな
listに変更する

280:デフォルトの名無しさん
08/10/31 12:29:08
vectorなら単にインデクスアクセスすりゃいいんじゃね?

281:デフォルトの名無しさん
08/10/31 12:58:07
インデックスも保持しといたらあてにならんだろう

282:デフォルトの名無しさん
08/10/31 13:13:01
push_backしかしないならインデックスは変わらんだろ

283:デフォルトの名無しさん
08/10/31 15:29:09
インデックスはとある理由で禁書されている。

284:デフォルトの名無しさん
08/10/31 15:45:12
push_backしかしない場合、dequeのイテレータは無効になるが
参照やポインタは無効にならない。

微妙に便利な時もあるかもしれない。

285:デフォルトの名無しさん
08/10/31 16:25:56
push_backしかしない場合インデックスは変わらないだろうけど
参照とかポインタは変わるだろ

286:デフォルトの名無しさん
08/10/31 16:57:59
vectorならな
dequeだと変わらない

287:デフォルトの名無しさん
08/10/31 17:25:06
dequeもメモリ続いてるから、足りなくなったら再確保されてアドレス変わらね?

288:デフォルトの名無しさん
08/10/31 17:48:20
> An insert at either end of the deque invalidates all the iterators to the deque,
> but has no effect on the validity of references to elements of the deque.

先頭と末尾への挿入は、イテレータは無効にするが要素への参照は無効にしない。

289:デフォルトの名無しさん
08/10/31 17:53:24
↑は規格書の 23.2.1.3 deque modifiers のところね。

290:デフォルトの名無しさん
08/10/31 17:53:27
>>287
deque<T>の仕様をとてつもなく乱暴に要約すると、
vector<T*>みたいな構造になってる。
だから拡張されても要素自体のアドレスは変わらない。


291:デフォルトの名無しさん
08/10/31 17:55:25
ちなみに両端以外への挿入はイテレータも参照も無効になるから注意

292:デフォルトの名無しさん
08/10/31 18:37:10
>>287
ランダムアクセスできるだけでメモリは続いてないでしょ?

293:デフォルトの名無しさん
08/11/01 01:17:19
とうとうお前らがdequeのスゴさに気づく時が来た

294:デフォルトの名無しさん
08/11/01 01:20:50
いや知ってて当たり前のことばかりだから

295:デフォルトの名無しさん
08/11/01 01:21:28
dequeの使いどころがわからん

296:デフォルトの名無しさん
08/11/01 01:29:23
上から取ったり、下から取ったり、南京玉簾のような使い方をする場合、dequeほど使えるコンテナは無いぞ。

297:デフォルトの名無しさん
08/11/01 01:49:09
「dequeは結構すげえんだぜ!」
っていうデータをまとめた記事(英語)が以前貼られてたね。

298:デフォルトの名無しさん
08/11/01 09:50:07
>>295
・ランダムアクセスしたい
・要素を加えたり抜いたりすることがある

そういうときに使う。
vectorでやると要素の追加・削除で領域を連続にするためのコストがかかる。

299:デフォルトの名無しさん
08/11/01 11:40:49
listはイテレータを記録すれば、ランダムアクセスできるよね?
イテレータが無効になる場合ある?

300:デフォルトの名無しさん
08/11/01 11:48:27
つうかイテレータ記録すればどんなコンテナだろうとランダムアクセスできるんじゃね

301:デフォルトの名無しさん
08/11/01 12:57:27
話の焦点が「イテレータを記録するモノ(コンテナなり何なり)」の機能に移るだけだよな、それ。

302:デフォルトの名無しさん
08/11/01 14:17:32
>299
結局 vector<list<something>::iterator> みたいなのを使うことになって
vector が登場する罠

303:デフォルトの名無しさん
08/11/01 17:56:00
つまり
boost::multi_index
の話しに

304:デフォルトの名無しさん
08/11/02 00:29:30
dequeのbuffer sizeってなんぼぐらい?

vc7,8は16bytes
gcc3.4.4(cygwni)は512bytes

vcの16って小さくね?
stringなんかはlistと同じになっちゃわないか

このサイズを指定できるdequeがほしいんだが
boostにあったりするかなあ

305:sage
08/11/02 02:27:17
すみませんです。
listのiteratorって、
要素の追加とか削除とかして要素数が変わってしまっても、
そのまま使える保証はあるんでしょうか?
要素の参照は保証されている思うんですが、iteratorが使えるのか。
VCでは実際動くみたいですが言語仕様的にいかがなものか。
ぜひアドバイスおねがいします。

306:デフォルトの名無しさん
08/11/02 02:48:55
保証されている。アドバイスとしては仕様書読め。

307:デフォルトの名無しさん
08/11/02 02:51:24
付け加えると削除したイテレータ自体は当然無効になる。

308:sage
08/11/02 03:15:01
早速の返答ありがとうございます!
ブラボーlist!使いやすさ爆発です。
そして以後ちゃんと仕様書読むようにします。
ありがとうございました。m(_ _)m

309:デフォルトの名無しさん
08/11/02 10:20:03
VC使ってる時点で言語仕様も糞も無いと理解しろ。

310:デフォルトの名無しさん
08/11/02 11:41:22
VC++6.0の頃じゃないんだから
今は結構まともだよ

311:デフォルトの名無しさん
08/11/02 12:10:26
VC++2008と仕様書との相違点はそれほど多くない。
書いてないだけで、これ以外にもあるのかもしれないがw
URLリンク(msdn.microsoft.com)

312:デフォルトの名無しさん
08/11/02 13:37:16
むしろgccのほーが異端

313:デフォルトの名無しさん
08/11/02 13:45:55
それはない

314:デフォルトの名無しさん
08/11/02 14:30:28
MFC(笑)
ATL(笑)

315:デフォルトの名無しさん
08/11/02 15:35:16
急にどうした?

316:デフォルトの名無しさん
08/11/02 15:45:00
dcc最強

317:デフォルトの名無しさん
08/11/02 20:53:06
ecc最強



翻訳的な意味で

318:デフォルトの名無しさん
08/11/04 13:56:24
BCCはどうよ
C++Builder2009にはBoost標準添付だったが

319:デフォルトの名無しさん
08/11/04 14:33:06
Boostって行っても1.35、しかもフルセットでなくてサブセットだけどな

320:デフォルトの名無しさん
08/11/05 11:45:38
map<string int> hoge;

mapを宣言したとき、intの領域は初期化されているんでしょうか?

されていないとしたら、

map<string,int>::iterator itr;
map<string,int>::iterator itrEnd;

itr = hoge.begin();
itrEnd = hoge.end();

while(itr != itrEnd){

itr->second = 0;
itr++;
}


のように初期化すればいいんですかね?

321:デフォルトの名無しさん
08/11/05 11:58:44
ちがう

322:デフォルトの名無しさん
08/11/05 12:00:49
なんで初期化したいんだろうか

323:デフォルトの名無しさん
08/11/05 12:12:16
intのほうでカウントとりたいんです

324:デフォルトの名無しさん
08/11/05 12:33:11
map<string int> hoge;

だけだと map コンテナの中身は空っぽだから
string も int もまだ領域確保されていなくて
デフォルト初期化も値初期化もはじまっていない
空のコンテナの begin() と end() は無効な要素を指している
無効な要素に対するアクセスは失敗する

itr->second = 0; // やっちゃらめぇ

だと思います

325:デフォルトの名無しさん
08/11/05 12:47:23
空のコンテナなら begin() == end() にならないんだっけ?
そうなるなら>>320を走らせちゃってもアクセス違反にはならないが

326:デフォルトの名無しさん
08/11/05 12:51:39
>>324
なるほど

void func(){

map<string int> hoge;

}

の関数内で宣言した場合、関数が呼び出される度に 空っぽになるんでしょうか?

327:デフォルトの名無しさん
08/11/05 13:04:07
呼び出される度にbegin()==end()になります

328:デフォルトの名無しさん
08/11/05 13:16:46
hoge["str"] ++;

とやればちゃんと0から加算されるんですか?

329:デフォルトの名無しさん
08/11/05 13:17:25
空のコンテナのイテレータはbegin()==end()になるって保証は
規格書に書いてあるの?

330:デフォルトの名無しさん
08/11/05 13:18:24
>>328
vectorとmapを混同するな

331:デフォルトの名無しさん
08/11/05 13:19:34
>>328
規格ではmapにoperator[]を適用した場合もしそのキーが
存在しない時はデフォルトのコンストラクタで初期化される
決まりになってるからint()、つまり0から始まる

332:デフォルトの名無しさん
08/11/05 13:22:43
>>329
23.1.7


333:デフォルトの名無しさん
08/11/05 13:25:49
>>330
どの辺を混同していますか?

334:デフォルトの名無しさん
08/11/05 13:25:53
>>332
サンクス
これは目から鱗だ

335:デフォルトの名無しさん
08/11/05 20:23:33
iteratorの位置を動かすとき
++it とかするけど it+=8 のような感じで8個分移動する方法はないの?

336:デフォルトの名無しさん
08/11/05 20:26:55
>>335
advance

337:デフォルトの名無しさん
08/11/05 20:27:32
もちろん、ランダムアクセス可能なイテレータはit += 8で平気。

338:デフォルトの名無しさん
08/11/05 20:36:44
listなのでループで回すしかないか

あと、ある値を持つコンテナを検索する関数を作ったのだが
見つからなかった場合NULLを返そう思ったら
itにNULL代入できない。しかも it ==0とか演算も不可
このような場合みんなはどうしてるん?

339:デフォルトの名無しさん
08/11/05 20:40:21
>>338
end返すのはいやなのか?

340:デフォルトの名無しさん
08/11/05 20:47:32
thx、打開した

341:デフォルトの名無しさん
08/11/05 21:25:09
そもそもfindでいいんじゃね

342:デフォルトの名無しさん
08/11/05 21:28:59
stlportのhash_mapにお尻から回す奴はないですか?

343:デフォルトの名無しさん
08/11/05 21:33:23
イチジク浣腸はどうだ

344:デフォルトの名無しさん
08/11/05 21:53:29
rbegin() rend()

345:デフォルトの名無しさん
08/11/05 22:49:22
叙述関数には引数わたせないの?
find_if( List.begin(), List.end(), compare( 引数1 、 引数2 ) );

346:デフォルトの名無しさん
08/11/05 22:56:09
ファンクタを使えばいくらでも。

347:デフォルトの名無しさん
08/11/06 16:02:53
>>342
vcのstdext::hash_mapならreverse_iteratorがあるぞ

348:デフォルトの名無しさん
08/11/07 00:51:20
VC2008とSTLpらすか5.1.7ですけど
_STLP_USE_STATIC_LIBを指定すると
↓と言われてリンクできません。
ファイル 'stlportstld_statix.5.1.lib' を開くことができません。

stlportstld_static.5.1.libならあるんですけど。バグですか?

349:デフォルトの名無しさん
08/11/07 01:02:22
ren stlportstld_static.5.1.lib stlportstld_statix.5.1.lib

350:デフォルトの名無しさん
08/11/07 01:12:47
#define _STLP_NEW_PLATFORM_SDK 1

351:デフォルトの名無しさん
08/11/08 12:18:23
VB6からVC++2005にプログラムを移植してるんですが、
下記の処理がVB版に比べてVC++版では50倍ほど時間がかかりました。
1から順に使われていないID番号を探すアルゴリズムで、内容は全く同じですが、なぜでしょうか?
m_itemは構造体配列で、要素数は600個程度です。
VC++のstd::vectorの実装はクソすぎなんでしょうか?

■VBの処理

Dim i As Long, j As Long
For i = 1 To 65535
 For j = 0 To m_item_num - 1
    If m_item(j).id = i Then Exit For
 Next
  If j = m_item_num Then
   get_new_item_id = i
   Exit Function
 End If
Next

■VC++の処理

size_t i, j;
for( i= 1; i< 0xFFFF; i++ ){
 for( j= 0; j< m_item.size(); j++ )
   if( m_item[j].id == i )  break;
 if( j == m_item.size() )  return i;
}

352:デフォルトの名無しさん
08/11/08 12:36:59
>>351
const size = m_item.size();
for(j = 0; j < size; ...

キミのままだと、jのループ後とにm_item.size()関数が評価される。

353:デフォルトの名無しさん
08/11/08 12:47:16
VC2005だとm_item[j]が毎回範囲チェックされてる
vector使う前に
#define _SECURE_SCL 0を入れると良い感じらしい

あと、まさかとは思うけどDebug版じゃなくて
Release版で実行してないとかはないよね?


354:デフォルトの名無しさん
08/11/08 12:58:48
そもそもループを1重に直したら(VBでもC++でも)もっと速くなると思う。

355:デフォルトの名無しさん
08/11/08 12:59:39
setでも使えばいいのに、とも思った

356:デフォルトの名無しさん
08/11/08 13:01:24
VBは知らないけど、C++のただの配列とvectorとでも50倍も差はないから、なんか他の要因で遅くなってると思われ。

357:デフォルトの名無しさん
08/11/08 13:02:15
あーごめんそれは無理か

358:デフォルトの名無しさん
08/11/08 14:00:46
終了条件おかしくないか?

359:デフォルトの名無しさん
08/11/08 14:07:46
351ですが、

>>352が主な原因だったようです。>>353でも多少改善しました。
二重ループをやめて、qsort()でもしてから一重ループで探すというのもいいかもしれませんが、
アルゴリズムを変更しないとVBより遅くなるというのは腑に落ちませんね。

ベクターは使い方次第でパフォーマンスに劇的に影響するようで、なんか怖いです。

360:デフォルトの名無しさん
08/11/08 14:24:53
VC2008のvectorで
if (int i = 0; i < tbl.size(); i++) tbl[i] ・・・
みたいな使い方と、
配列で、
if (int i = 0; i < TBL_SIZE; i++) tbl[i] ・・・
みたいな使い方をした場合、
Debugビルドで最適化なしだと数十倍の差で、Releaseビルドで、最適化ありだと、二倍程度の差だった。

361:デフォルトの名無しさん
08/11/08 14:26:01
このスレ的にはiterator使おうぜ

362:デフォルトの名無しさん
08/11/08 14:31:04
>>359
VB知らないんだけど、この場合のm_item_numってなに?
それ次第では、そもそも「内容は全く同じ」という認識が間違ってたことに。

363:デフォルトの名無しさん
08/11/08 14:35:47
VBとコードが違わないか?
>for( i= 1; i< 0xFFFF; i++ ){
for( i= 1; i<= 0xFFFF; i++ ){

調べてる要素が違ってるなら50倍違ってもおかしくはないけど。
あとは計測時間が短すぎて時間を計ってるタイマーの精度の違いが出てるとか
とりあえず>>351のコードをReleaseビルド&_SECURE_SCLでコンパイルしてVBより50倍も遅いなんてことあり得ないだろ。

364:デフォルトの名無しさん
08/11/08 14:53:51
>359
ちゃんと最適化かけたか?

365:デフォルトの名無しさん
08/11/08 15:06:10
STLがVBに負けるなんて悔しい ビクンビクン

366:351
08/11/08 15:08:04
すみません。デバッグビルドになってたようです><
なんかデバッグなしにしたり最適化とかするとエラーが出てコンパイルできなかったので、何となく諦めてました。
>>359をやった上で最適化まですると、VBより速くなりました。
めでたしめでたし。

367:デフォルトの名無しさん
08/11/08 15:10:02
しね

368:デフォルトの名無しさん
08/11/08 15:12:42
まさにVB脳

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が(償却じゃなくて正真正銘の)定数時間であることは規格で要求されてたはず
だから一概に実装に依るとも言えない


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch