【C++】STL(Standard Template Library)相談室 10 at TECH
[2ch|▼Menu]
1:デフォルトの名無しさん
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)
・解説
Wikipedia項目リンク
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
d

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回舐めればいいだけだから、たいした問題ではないか
なんちって


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

4649日前に更新/158 KB
担当:undef