【C++】STL(Standard Template Library)相談室 7

このエントリーをはてなブックマークに追加
1デフォルトの名無しさん
C++標準ライブラリの一つ、STLについて。

前スレ

【C++】STL(Standard Template Library)相談室 6
http://pc11.2ch.net/test/read.cgi/tech/1160821240/

過去ログ・リンク・書籍紹介は >>2 以降
2デフォルトの名無しさん:2007/08/02(木) 01:51:45
過去ログ

【C++】STL(Standard Template Library)相談室 5
http://pc8.2ch.net/test/read.cgi/tech/1143608073/
【C++】STL(Standard Template Library)相談室 ;4
http://pc8.2ch.net/test/read.cgi/tech/1130680264/
【C++】STL(Standard Template Library)相談室 3
http://pc8.2ch.net/test/read.cgi/tech/1116559700/
【C++】STL(Standard Template Library)相談室 2
http://pc8.2ch.net/test/read.cgi/tech/1104898734/
【C++】STL(Standard Template Library)相談室
http://pc5.2ch.net/test/read.cgi/tech/1095583235/
3デフォルトの名無しさん:2007/08/02(木) 01:54:38
4デフォルトの名無しさん:2007/08/02(木) 02:00:43
書籍紹介


STL標準講座―標準テンプレートライブラリを利用したC++プログラミング
http://www.amazon.co.jp/gp/product/4881357786/

STL―標準テンプレートライブラリによるC++プログラミング 第2版
http://www.amazon.co.jp/gp/product/4894714329/

標準C++:STLの基礎知識
http://www.amazon.co.jp/gp/product/4756138047/

標準講座C++―基礎からSTLを利用したプログラミングまで
http://www.amazon.co.jp/gp/product/4881357050/

STLによるコンポーネントデザイン
http://www.amazon.co.jp/gp/product/475613422X/

Effective STL―STLを効果的に使いこなす50の鉄則
http://www.amazon.co.jp/gp/product/4894714108/
5デフォルトの名無しさん:2007/08/02(木) 02:02:58
6デフォルトの名無しさん:2007/08/02(木) 02:15:51
とりあえず立てときました。

//////////////////////////////////////////////////////////
// 更新履歴
//
// [テンプレに関して]
//
// 2007/08/02
// ・リンク切れのページがあった為、そのリンクを外しました。
// ・書籍、amazonのリンクが長すぎる為、短く変更しました。
//
//////////////////////////////////////////////////////////
7デフォルトの名無しさん:2007/08/02(木) 02:22:20
結局立てちゃったのね
8デフォルトの名無しさん:2007/08/02(木) 02:33:34
定期的にboostや0xの話題出して統合を促すしかないようだな
お前らも協力しろよ
9デフォルトの名無しさん:2007/08/02(木) 02:52:27
>>8
準標準のboostと標準のSTLのスレを統合するのはどうかと思う。

主観やけど難易度としては boost > STL だと思ってるから、
統合したら、STL入門者の居るスレで、boostの新コンポーネントの話はし辛い。

今までどおり、

「std::auto_ptr満足できねー」
「つ boost::shared_ptr」

って流れでいいかと。

0x専用のスレは・・・無くても・・・いいかな。
10デフォルトの名無しさん:2007/08/02(木) 03:39:43
とりあえず貼っとく。

http://pc8.2ch.net/test/read.cgi/tech/1104898734/562

562 名前:デフォルトの名無しさん[sage] 投稿日:2005/05/05(木) 02:58:39
"STL"なんて呼称の範囲は、C++の標準ライブラリに
取り込まれてしまった今となっては明確に区切れる物では無い。
HP STL や SGI STL のことを指して言ってるのかもしれないが、
今使われてるのはそれらをベースにしたC++標準ライブラリだ。
範囲が明確に決まってるかのように、含まれるだの含まれないだの言うのは時代遅れだぞ。

このスレが不要である事に疑いの余地は無い。
11デフォルトの名無しさん:2007/08/02(木) 05:45:07
お前が勝手に考えた基準に従う必要は無い。
12デフォルトの名無しさん:2007/08/02(木) 06:06:25
>>11
まぁお前の考えが下に続いていれば少しは格好もついたけど、
そんなヒステリーじゃ話にならないな。
13デフォルトの名無しさん:2007/08/02(木) 06:17:45
>>9
boostってなに?
14デフォルトの名無しさん:2007/08/02(木) 06:21:26
屁の音
15デフォルトの名無しさん:2007/08/02(木) 06:46:00
>>12
やっぱ、自分で書いたものをコピペしてたのか
よっぽど、いいこと書いたと思ってんだなw
16デフォルトの名無しさん:2007/08/02(木) 07:08:49
何が「やっぱ」なのか意味不明なんだが。
変な電波受信してるんじゃないか?
ヒステリーって言われたのがこたえたのかな。
17デフォルトの名無しさん:2007/08/02(木) 08:02:10
>>8どっちも専用スレあるだろ。
TR1、TR2の話題ならここでもよかろ
18デフォルトの名無しさん:2007/08/02(木) 09:16:48
>>10の頭の弱そうなスレみつけてちょっと遊んでみました。
ごめんなさいもうしませんこたえました。
19デフォルトの名無しさん:2007/08/02(木) 11:08:08
また立てちゃったの?
20デフォルトの名無しさん:2007/08/02(木) 13:47:33
立った以上はまあ、有効活用するしかない。
21デフォルトの名無しさん:2007/08/05(日) 14:03:04
そこで鮮やかに俺が初歩的な質問に有効活用ですよ

vector<T> hoge; // 自作クラスのコンテナ
vector<size_t> fuga; // 上記コンテナの添え字コンテナ

・・・な配列があったとして、以下の処理をループ使わずにやるにはどうすりゃいいですか?

vector<T> result;
for (vector<size_t>::iterator it = fuga.begin(); it != fuga.end(); ++it)
{
result.push_back(hoge[*it]);
}

多分こんな感じになるんじゃなかろうかと思うんだけど、

for_each (fuga.begin(), fuga.end(), ??);

これしきの代入に関数オブジェクト自作して放り込むのも大げさな気がして
予め用意されてる関数とかでサクッとできる方法ってあります?
22デフォルトの名無しさん:2007/08/05(日) 14:29:12
back_inserter使ったらだめなん
23デフォルトの名無しさん:2007/08/05(日) 14:35:58
boost::permutation_iterator
24デフォルトの名無しさん:2007/08/05(日) 14:40:51
さくっと
typedef vector<T>::reference(vector<T>::*at_t)(vector<T>::size_type);
transform(fuga.begin(),fuga.end(),back_inserter(result),bind1st(mem_fun(static_cast<at_t>(&vector<T>::operator[])),&hoge));
25デフォルトの名無しさん:2007/08/05(日) 14:41:05
>>21
ここらへん組み合わせればなんとかなりそう。
transform back_inserter mem_fun vector::operator [] または at
2625:2007/08/05(日) 14:46:44
うは >>24 乙。
bind1st が抜けてたか。

しかし、これは読みにくいな。
27デフォルトの名無しさん:2007/08/05(日) 15:00:55
STLスレって結局Boost使えばこうできるって話になるから嫌。
分けないで前みたいなC++テンプレートスレみたいにでもすればいいんだ。

23の言っているboost::permutation_iteratorだとこんな感じ。
result.reserve(hoge.size());
std::copy(
  boost::make_permutation_iterator(hoge.begin(), fuga.begin()),
  boost::make_permutation_iterator(hoge.end(), fuga.end()),
  std::back_inserter(result));
28デフォルトの名無しさん:2007/08/05(日) 15:13:33
うお・・・transform + back_inserter ってこういう使い方できるのか・・・
「何らかの処理施してコピー」なんて解説されてるの読んでピンと来ず。。
「別のコンテナの中身を引っ張ってくる」って処理もアリなわけね。

今回の例みたいな単純な代入だとループに逃げそうになるチキンな俺だが
しかしこれを手がかりに色々と応用試せそうだぜ!おまいら愛してる!
29デフォルトの名無しさん:2007/08/05(日) 15:20:14
std::copy + ostream_iterator
STL習いたての時、で画面にprintできる事に感動したなぁ
30デフォルトの名無しさん:2007/08/05(日) 15:25:10
試すのはいいけど、そういう書き方ってみんなしてるもんなの?
個人的には >>24 みたいなコードあんまり読みたくない・・・
3127:2007/08/05(日) 15:41:57
俺はやらない。だってBoostがあるから。
32デフォルトの名無しさん:2007/08/05(日) 15:43:06
BOOST_FOREACH(size_t val,fuga)
{
 result.push_back(hoge[val]);
}
3321:2007/08/05(日) 16:01:17
今まで標準に含まれてるstlすらマトモに使えてないのにboostに手を出すと
俺の頭がboostするに違いないと思って手をつけなかったのだが・・・
いい機会だから試してみようかしら。
どう思われる? transformとかもマトモに使いこなせてない俺なわけだが。

今なんか const なメンバ関数を mem_fun に投げ込もうとして
コンパイラに長々と説教頂いておりますよ
34デフォルトの名無しさん:2007/08/05(日) 16:13:54
>>33 知るか。好きにしろ。
35デフォルトの名無しさん:2007/08/05(日) 16:15:51
smart_ptrをはじめ、cstdint, static_assert, utilityなんか使いこなすも何も無いだろ?
3624:2007/08/05(日) 16:18:29
>>30
あんな自己満足コードを正気で書く奴は(多分)いないね。
あんなコードを仕事で見せられたら俺なら殴るね。

3721:2007/08/05(日) 16:36:33
>>36
もう少しで殴られるとこだったか(・∀・;
今回の例程度の状況ならさっさとループで済ませて次にかかるとしよう
いずれにしても今回教えてもらった事は他の場面で活用するぜ
boostも近いうち試してみる
38デフォルトの名無しさん:2007/08/05(日) 17:54:48
はしかみたいなもんかもな

「ループ使ったら負け」とかいう病気
39デフォルトの名無しさん:2007/08/05(日) 18:06:43
仕事ならループにするなあ
メンテは自分だけがやるわけではないし
40デフォルトの名無しさん:2007/08/05(日) 21:41:38
どうせループでも関数合性でも読みにくいんだから慣れが要らないループの方が増し。
41デフォルトの名無しさん:2007/08/05(日) 22:06:24
// 上のコードは以下のループと同等
// ...

って両方のっけとく。
そしてわざわざ1行に下意味をなさなくなる
42デフォルトの名無しさん:2007/08/05(日) 22:43:27
foreach (counter i, counterble_range(start,end)) { ... }
ぐらいなら読める人結構いると思うぜ
43デフォルトの名無しさん:2007/08/14(火) 01:11:34
STLやるなら、やっぱEffectiveSTLは必読?
44デフォルトの名無しさん:2007/08/14(火) 01:57:27
>>43
書いてある内容を知ってないといろいろ嫌なことが起こるだろうとは言える。
Web 上にも同様の情報はあるので、本が必要なわけじゃない。
45デフォルトの名無しさん:2007/08/14(火) 11:32:13
読み物としてはそこそこ面白かった。
必要とか不必要とかじゃなく「おすすめの一冊」
46デフォルトの名無しさん:2007/08/14(火) 14:29:30
勉学に近道なしというが、読めば道程を多少なりともショートカットできる稀有な本。
47デフォルトの名無しさん:2007/08/14(火) 19:25:17
ちょいと質問。
template<typename T> void func(std::vector<T> foo)
{
std::vector<T>::iterator it;
}
こういうことをしようとするとerror: expected `;' before "it"になるのだけれど
なんかいい方法はないだろか。要は、forループで使いたいわけだが。
48デフォルトの名無しさん:2007/08/14(火) 19:28:31
typename std::vector<T>::iterator it;
4947:2007/08/14(火) 19:36:27
>>48
なるほど、失念していた。THX!
50デフォルトの名無しさん:2007/08/16(木) 16:27:03
晒してみるテスト。
ttp://www5c.biglobe.ne.jp/~ecb/cpp/07_18_03.html
>fill_n void fill( FwdIt first, Size n, const T& x ) firstからn個分の要素をxで満たします。
おいおい、コピペミスにもほどがあるぞ。

ttp://www005.upp.so-net.ne.jp/episteme/html/stlprog/algorithm.html#algorithm
>- template<class OutputIterator, class Size, class T>
> void
> fill_n(OutputIterator first,
> Size n,
> const T& value);
あれ? エピたん……

ttp://www.s34.co.jp/cpptechdoc/reference/stl_samples/algorithm.html#std_fill
>- template<class OutputIterator, class Size, class T>
> void
> fill_n(OutputIterator first,
> Size n,
> const T& value);
おやー? しかもここ、エピたんのぺーじにそっくりだけど。

ttp://docs.sun.com/source/819-3704/fil_4628.htm
>template <class OutputIterator, class Size, class T>
> void fill_n(OutputIterator first, Size n, const T& value);
あれ、ここもか。
fill_n()がOutputIteratorを返すってのはローカルな拡張なのか?

ttp://www.informatik.uni-freiburg.de/~danlee/fun/STL-doc/STL/Fill.html
ttp://www.wakhok.ac.jp/~sumi/stl/header/algorithm.html
この辺を初め、OutputIteratorを返すとしているところも多々あるにはあるのだが……
51デフォルトの名無しさん:2007/08/16(木) 17:31:39
規格見りゃ分かる

template<class OutputIterator, class Size, class T>
void fill_n(OutputIterator first , Size n , const T& value);
5250:2007/08/16(木) 18:05:56
ほほぉ、THX!
すると、1番目は論外として、2-4番目は正解ってことね。
# まぁ、4番目の丸ごとコピー疑惑はあるにしても。
で、5-6番目はgccの拡張を取り上げたのかな?
53デフォルトの名無しさん:2007/08/16(木) 18:25:07
へー、
引数が前方反復子だと戻り値がvoidで、出力反復子だと出力反復子になる実装があるのか。
具体的になにが便利でどう使い分けるのかがよく分からないけど…
5450:2007/08/16(木) 18:55:51
>>53
いや、1番目のは間違いだらけだから無視して。
で、gccの実装はこう。
--
template<typename _OutputIterator, typename _Size, typename _Tp>
_OutputIterator
fill_n(_OutputIterator __first, _Size __n, const _Tp& __value)
--
つまり、fill_n()は__first + __nを返す仕様になっている。
55デフォルトの名無しさん:2007/08/16(木) 19:15:13
libcomoも_first+nだった。SGISTLの実装っぽいなぁ
56デフォルトの名無しさん:2007/08/16(木) 19:19:02
std::vector、listでのeraseの使い方で質問があります。
eraseで指定された要素を削除する場合、ifで分けて以下のような操作をしなければならないのでしょうか?
なんか、if,elseで分けるところが美しくないのですが、もっと良い書き方があれば教えてください。

std::vector<int> array;
↑には複数の要素があるとする
std::vector<int>::iterator itr;
for (itr = array.begin(); itr != array.end();) {
if (*itr == 5) {
itr = array.erase(itr);
} else
itr++;
}
}
57デフォルトの名無しさん:2007/08/16(木) 19:20:54
事前にremove_ifでいらない要素をうっちゃってからerase
これ基本
58デフォルトの名無しさん:2007/08/16(木) 19:26:01
5と等しいかどうかで削除してるんだから
ただのremoveでよくね?
5956:2007/08/16(木) 19:40:08
>>57-58
できました。ありがとうございます。
struct Hoge{
int a;
int b;
};
という構造体があり、intのコンテナではなく
std::vector<Hoge>
だった場合、
Hoge構造体のaの値を見て、削除する場合はどうすればいいのでしょうか?
60デフォルトの名無しさん:2007/08/16(木) 19:51:36
if (* itr == 5)

if (itr->a == 5)
61デフォルトの名無しさん:2007/08/18(土) 23:02:48
operator int()
{
return a;
}
62デフォルトの名無しさん:2007/08/23(木) 23:23:37
>>61
一瞬惚れそうになったが
intに直接変換できちゃ困るかもしれん。
比較のためだけのクラスを作って、それに変換するってのはどうだ?
(関数オブジェクト作る方がいいんだろうけど)
63デフォルトの名無しさん:2007/08/24(金) 01:06:12
vectorについて質問します。

class Parts{
 略
}
class A {
 Parts* parts;
 A(){
  parts = new Parts();//コンストラクタで生成して
 }
 ~A(){
  delete parts ;//デストラクタで破棄する
 }
 略
}

というようなクラスがあったとしてそれをvectorに格納したいとき

std::vector<A> vec;

function(){
A a ;
vec.push_back(a) ;
}

とすると、Aクラスのデストラクタが2回呼び出されて
中身の無いポインタをdeleteしてエラーになるようです。
なぜvectorがデストラクタを呼ぶのかなどなぜなのかとどうすればいいか
詳しく解説があるようなところがあれば教えてください。

素人考えでは
やはりSTLの補完としてのBoostのスマートポインタが必要なのでしょうか。
64デフォルトの名無しさん:2007/08/24(金) 01:14:04
>>63
vector<>に格納する時にAのコピーコンストラクタが呼ばれるが、
Aではそれが定義されていないので、デフォルトのコピーコンストラクタが
呼ばれ、ポインタメンバのpartsが単にコピーされる。

結果として出来るAのインスタンスは2個だが、どっちもpartsは
同じPartsインスタンスを指しており、それぞれのAが破棄されるときに当然
問題が起きる。

まともに機能するコピーコンストラクタを自分で定義する(この場合は
多分リファレンスカウントを自分で実装することになる)か、
Partsのポインタではなくリファレンスカウント式のスマートポインタを
持つようにするんだな。
65デフォルトの名無しさん:2007/08/24(金) 01:23:17
>64の通りだが、まずはEffective STL読め。
stlコンテナは常にコピーコピーコピーコピーコピーコピーコピー。
安全にコピーできるオブジェクトでなければコンテナに入れちゃいけない。

慣れてきたらリソースの所有権について常に考えるようにすると良いよ。
66デフォルトの名無しさん:2007/08/24(金) 01:24:21
>>63
class A のメンバに
A(const A &x) : parts(new Parts(*x.parts)) {}
を追加するとかそういう意味合いもあったりなかったり

現状の class A 自体が class としての機能を満たしてないから
ちゃんと実装してやった方がおばちゃんモアベターよ
67デフォルトの名無しさん:2007/08/25(土) 01:51:41
63です。

64 65 66 のみなさま、
迅速、かつ誘導ではなくこちらでお答えくださってありがとうございます。
なぜpush_back()でデストラクタが呼ばれるかは分かりませんが、
コピーコンストラクタの実装で解決できることを理解できました。

>64
同一のインスタンスでなくてもよかったので(概略からはわかりませんが)
新しくインスタンスを作って値はすべて同じでいちおう動きました。

>65 >コンテナは常にコピー
補足、アドバイスありがとうございました。

>66
STLと別の話になってしまいますが
クラスとしての機能とはどんなものでしょうか。
それが私にはまだ分かっていないので>63のような質問をすることになるのかもしれません。
68デフォルトの名無しさん:2007/08/25(土) 02:08:28
悪いこと言わんからEffective STL読め。
手っ取り早くはboost::shared_ptr使うのがベター

class Parts{
 //略
}
class A {
public:
 A() : parts_(new Parts) {}
private:
 boost::shared_ptr<Parts> parts_;
 //略
}
69デフォルトの名無しさん:2007/08/25(土) 02:12:43
> なぜpush_back()でデストラクタが呼ばれるかは分かりませんが、

RAIIを勉強しなさい。

function()のスコープを出るときにA aが破棄されるのでデストラクタが呼ばれる。
あと、std::vectorはどの時点で内容をコピー&破棄するか判らないので、
function()のスコープの前にデストラクタが呼ばれる可能性もある。

結局のところ、class Aはコンテナに納める要件を満たしてないので入れちゃダメ。
70デフォルトの名無しさん:2007/08/25(土) 14:06:45
すみません初歩的な質問なんですけど
using namespace std;
って使わない方がいいって良く言われますけど、
面倒でも std::vector<> って使った方がよいのでしょうか?
71デフォルトの名無しさん:2007/08/25(土) 14:11:52
ヘッダ内で using namespace 〜 を使うとまずいような「気がする」という話だからなぁ
自分だけで使うことが確定してるヘッダなりプロジェクトなりだったらガンガン使おうがNP

using std::vector;
とかで以後 vector<type> として使えるからごく個人的にはこっちをお勧めしておきたくて愛
72デフォルトの名無しさん:2007/08/25(土) 14:21:16
>70
影響範囲を考えて判断すべし。
・ヘッダ(関数スコープ外): 他のソースにも影響するから避ける
・ソース:全てのヘッダをインクルードした後ならば影響は小さい。
・関数スコープ内:問題なし。問題あったら関数を修正。
なんで、ケースバイケースですな。
73デフォルトの名無しさん:2007/08/25(土) 14:22:36
>>70
少なくともヘッダの中で一切スコープで囲ってないとこでやるのは
止めといたほうがいいんじゃね
それがそのままソースにまで取り込まれるからな
自分のnamespaceなり何なりにくるんで、その中で使う分には、まあいいんじゃね
74デフォルトの名無しさん:2007/08/25(土) 20:19:44
よくわかりました
ありがとうございました
75デフォルトの名無しさん:2007/08/30(木) 21:42:59
int型のx,yをメンバとする構造体(data)をvectorに格納し、xを基準にソートしています。
ここで、xの値が特定の範囲内に収まっているもの(30〜50とか)を検索しようとしています。
lower_boundで下限側の検索はうまくできましたが、upper_boundによる上限側の検索がうまくできません。

lower_bound に渡す関数オブジェクトは以下のようにしてうまくいけてるようです。
struct Comp:public binary_function<const data&,const int& ,bool>
{
result_type operator()(first_argument_type prm1,second_argument_type prm2)const
if(prm1.x<prm2)
return true;
return false;
};
upper_bound 側についても上記と同じように書いてみたのですが、コンパイルエラー
などがでます。どのように記述すればよろしいでしょうか。
よろしくお願いします。
76デフォルトの名無しさん:2007/08/30(木) 23:07:40
知らんけど、 int < data を書かないといけないんじゃない?
77デフォルトの名無しさん:2007/08/30(木) 23:24:53
>75
同じようにっていうか、それをそのまま渡せばいいんじゃないの?
78デフォルトの名無しさん:2007/08/30(木) 23:26:14
早速の回答、ありがとうございます。
「int<data を書く」とは具体的にはどのようなことなのでしょうか?
よろしくお願いします。
79デフォルトの名無しさん:2007/08/30(木) 23:28:27
>>78
>>75は読んでないけど>>76の言ってる意味は
bool operator<(int, const data&) のことでは。
80デフォルトの名無しさん:2007/08/30(木) 23:42:01
>>77
low=lower_bound(array.begin(),array.end(),20,Comp());
この場合は正常に取得できます。
以下のようにupper_bound にそのまま渡したのですが
upp=upper_bound(array.begin(),array.end(),30,Comp());

この場合にコンパイルエラーがでてしまいます。
:1番目の引数をconst int からconst struct data& に変換できません。

>>79
bool operator<(int, const data&) を定義して関数オブジェクトを使用
しないほうがいいのでしょうか・・・。
そちらも試してみます。

81デフォルトの名無しさん:2007/08/30(木) 23:59:16
bool operator<(int, const data&)と
bool operator<(const data&,int) を定義しておけば
lower_bound(array.begin(),array.end(),20)
upper_bound(array.begin(),array.end(),30)で上限下限が取れました。
ですが、場合によってはメンバのyによる範囲検索もしたいので
以下のような関数オブジェクトを指定たいのです。
struct Comp:public binary_function<const data&,const int& ,bool>
{
int m_nType;
Comp(int nType){m_nType=nType;} //1:x比較 2:y比較
result_type operator()(first_argument_type prm1,second_argument_type prm2)const
{
if(m_nType==1)
{
if(prm1.x<prm2)
return true;
return false;
}
else
{
if(prm1.y<prm2)
return true;
return false;
}
}
};

どのようにすればよろしいでしょうか。
よろしくお願いします。
82デフォルトの名無しさん:2007/08/31(金) 00:33:52
upper_bound 用の、引数の順序を逆にした関数オブジェクトを作る
83デフォルトの名無しさん:2007/08/31(金) 00:46:14
関数オブジェクトはひとつでいいよ。オーバーロードを追加するだけでいい。
84デフォルトの名無しさん:2007/08/31(金) 18:48:57
>>82,83
ご回答、ありがとうございます。
無事解決できました m(__)m。
85デフォルトの名無しさん:2007/09/05(水) 22:06:05
listの2次元配列の質問です。
listの行の要素の増加をどういう風にすれば良いのかが分かりません。

list< list<int> > i;
i.pushback(100);

これではエラーが出てしまってできません。


もう一つ。
配列の列の要素の最初と最後の参照はできるのですが、
途中の要素の参照の仕方が分かりません。

list< list<int> >::iterator it = i.begin();
it.***->x = 1000; //***番目のxに1000を格納したい

1次元の配列だと問題ないのですが、2次元だと良く分かりません。
解決できる方、お願い致します。
86デフォルトの名無しさん:2007/09/05(水) 22:09:03
pushbackでは駄目だろうな
87デフォルトの名無しさん:2007/09/05(水) 22:11:20
っつうかlistのlistなのに「何番目」とかランダムアクセスしようとするのはアホだろ
deque使え
88デフォルトの名無しさん:2007/09/05(水) 22:54:53
>>87
ランダムアクセスというかfor文で順次アクセスしたかったんですけどね。
書き方悪かったです。

dequeですか。
ありがとうございます。listに拘りすぎました。
89デフォルトの名無しさん:2007/09/05(水) 23:16:09
>>88
typedef std::vector<int> line;
typedef std::vector<line> table;

line l;

l.push_back(1);
l.push_back(2);
l.push_back(3);

table t;

t.push_back(l);
t.push_back(l);
t.push_back(l);

std::cerr << t[1][1] << std::endl;

t[1].push_back(4);

std::cerr << t[1][3] << std::endl;
90デフォルトの名無しさん:2007/09/06(木) 02:50:07
>it.***->x = 1000; //***番目のxに1000を格納したい


>ランダムアクセスというかfor文で順次アクセスしたかったんですけどね


矛盾してますが何か?
91デフォルトの名無しさん:2007/09/06(木) 08:56:30
これがゆとりか ...
92デフォルトの名無しさん:2007/09/08(土) 02:24:40
ひょっとしてこんなコード書きたかったんだろうか。

list< list<int> >::iterator it = i.begin();
list<int>::iterator jt = it->begin()
for(int i = 0; i < 500; i++) {jt++;}
*jt = 1000; // 500番目に格納

う、うひぃ。 
93デフォルトの名無しさん:2007/09/08(土) 02:54:02
atd::advance
94デフォルトの名無しさん:2007/09/14(金) 19:08:48
初心者なんですがSTL使うと読みにくいです。
慣れの問題ですか?
95デフォルトの名無しさん:2007/09/14(金) 20:34:26
脳の問題
96デフォルトの名無しさん:2007/09/15(土) 01:28:14
初心者なんですがSTL使うと
エラーメッセージが頓珍漢で
原因ンが把握しにくいです。
慣れの問題ですか?
97デフォルトの名無しさん:2007/09/15(土) 01:58:29
脳の問題
98デフォルトの名無しさん:2007/09/15(土) 03:34:44
初心者なんですが
このスレの住人うざいです。
脳の問題ですか?
99デフォルトの名無しさん:2007/09/15(土) 03:51:53
慣れの問題
100デフォルトの名無しさん:2007/09/15(土) 13:05:16
>>98
うざければこのスレ開かなければいいだけの話。
お前は馬鹿。
101デフォルトの名無しさん:2007/09/15(土) 13:17:51
なにこのひと
102デフォルトの名無しさん:2007/09/15(土) 13:25:45
さぁ
103デフォルトの名無しさん:2007/09/15(土) 13:50:16
むきになんなよ
104デフォルトの名無しさん:2007/09/15(土) 14:40:57
STLをすてる
105デフォルトの名無しさん:2007/09/15(土) 20:12:19
Su
Te
Lu
106デフォルトの名無しさん:2007/09/15(土) 20:16:40
誰がうまいこと言えと
107デフォルトの名無しさん:2007/09/16(日) 00:51:07
STLって現場では当たり前に使われてるんですか?
108デフォルトの名無しさん:2007/09/16(日) 01:17:33
現場による。
「全員にSTL教育しないと読めない奴が出てくるから」って理由で禁止してる現場もあるし、
個人の裁量任せになってる現場もある。

しっかりモジュール分割がされてるプロジェクトだと
ヘッダファイルを読み込むだけだからSTLだろうがBoostだろうが許可されることも。

ちなみに俺のところは、
「コンパイラ付属のライブラリなら、コンパイラ屋がサポート責任を持つからOK」
って事になってる。
(バグ・ドキュメント不備を見つけたらMSにゴルァ)
109108:2007/09/16(日) 01:19:05
最後の行は、
「VCのバグを見つけたら」って意味ね
110108:2007/09/16(日) 01:28:31
ついでに
俺のところは社内で開発したライブラリが結構充実してるので
末端のコーディングでSTLを使う場面があまりない。

まあ、保守を考えたら、
末端があまりに前衛的なコーディングをしてたら嫌がられるだろうな。
Boostはともかく、
STLでも深入りすればそれなりのおつむレベルが要求されるから。
111107:2007/09/16(日) 01:43:20
なるほど。
現場次第なんですね。
うちではあまり使われてないです。
うちの現場はヘポーコなんで
リスト構造とかいちいち自前で作成してるアフォが多くて
112デフォルトの名無しさん:2007/09/16(日) 02:01:52
VC7.1のvectorとか怪しいと思ってる。

memset(&(v[0]), 0, v.size())
規格上は問題ないはずだが、これをやるとおかしくなる。

仕事ではSTLの利用は警戒した方がいいと思う。
113デフォルトの名無しさん:2007/09/16(日) 02:12:24
>>112
size()の戻り値は要素数じゃね?
memset()の最後の引数はバイト数じゃね?
114デフォルトの名無しさん:2007/09/16(日) 02:18:18
>>112
初心者乙
115デフォルトの名無しさん:2007/09/16(日) 03:40:21
>112
v の型は何よ?
116デフォルトの名無しさん:2007/09/16(日) 04:10:18
STLすら分からないって
よっぽど見るに耐えないコーディングしてるんだろうな。

美的センスのないコードはバグの温床になるから嫌い。
117デフォルトの名無しさん:2007/09/16(日) 11:24:31
自分とこの現場もかなりレベルが低い。
わからないのを人のせいにしてくる始末。
わからない人でもわかるようにコメント書けとかいってくるw
おまえが勉強しろよって感じ。技術者としてどうよって思う。
118デフォルトの名無しさん:2007/09/16(日) 11:35:36
ツールも規約も方法論も、現場のレベルに合わせて決めてるよ
そうしないと先にすすまないもん
119デフォルトの名無しさん:2007/09/16(日) 12:17:29
>>112
ひさびさにバイト長と要素数の間違い犯してる香具師みた。
誰もが一度は犯す過ちだよな…
120デフォルトの名無しさん:2007/09/16(日) 12:45:11
STL使えないレベルの現場だとC++使わせないのが正解だよな。
素人にチェーンソー使わせるなんて危なっかしいことしない方が良い。

でも、easy Cとして使えそうなのって他にないんだよな……用途限定でJavaぐらいか。
121デフォルトの名無しさん:2007/09/16(日) 12:52:38
そういうことでD言語だけど、すぐに一般化しそうな気配じゃないしな

>>119
バイト長とは変わった肩書きだなぁ、とかイミフなことを思ってしまった
122デフォルトの名無しさん:2007/09/16(日) 13:02:39
バイト見習い→バイト→バイト長
123デフォルトの名無しさん:2007/09/16(日) 13:12:45
バイトにまで上がれば出世は楽だけど、
ビット長からバイト見習いに上がるまでがきつい
124デフォルトの名無しさん:2007/09/16(日) 13:17:43
ニブルを経由するんだ!
125デフォルトの名無しさん:2007/09/16(日) 13:24:37
ボクはニプルのほうが好きです
126デフォルトの名無しさん:2007/09/16(日) 17:46:36
>>108は、VCの付属ならOKだけどSTLPortは不可ってことだよね?
”会社で使うコンパイラにSTL付属してるけど、他のSTL使ってる”って人はどんくらいいるのかな?
よければ教えて欲しい(なんとなく知りたいだけだから無視してくれてOK)。

うちは、STLPort使ってる。うちの会社の使い方でパフォーマンスよかったから。
127デフォルトの名無しさん:2007/09/17(月) 02:08:55
VC付属のを使っています Boostも使っています。
STLport を使うと早くなるのかなぁ〜
128デフォルトの名無しさん:2007/09/17(月) 05:03:18
#include <stdafx.h>
#include <iostream>
#include <vector>
#include <algorithm>

void show(int i)
{
std::cout << i << "\n";
}

int _tmain(int argc, _TCHAR* argv[])
{
std::vector<int> v;
int i;

for(i=0;i<10;i++){
v.push_back(i);
}

for_each(v.begin(),v.end(),show);

return 0;
}



↑のコードでshowに引数を書いてないのに
iが順番に出力されるのはなぜですか?
129デフォルトの名無しさん:2007/09/17(月) 05:56:50
>>128
for_eachが内部でshowを呼んでいるから。
130デフォルトの名無しさん:2007/09/17(月) 05:59:23
引数はどうやって判断するんですか?
131デフォルトの名無しさん:2007/09/17(月) 06:07:39
質問が成立してない。言い直してくれ。
132デフォルトの名無しさん:2007/09/17(月) 08:00:38
std::map に count メソッドがあるのはなぜですか?

count() // xをキーに持つ要素の数を返す。
size_type count(const key_type& x) const;

だそうなのですが、そもそも map だと x をキーに持つ
要素の数は高々1なので、count というよりは bool
で済む気がするのですが、これは multimap のことも
考えてのことですか?
133デフォルトの名無しさん:2007/09/17(月) 09:01:10
>>128
そのfor_each()は次のコードとほぼ等価だ。
--
for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) show(* it);
--
ついでに言えば、最適化によって次のコードともほぼ等価になる。
--
for (unsigned ic = 0; ic < ic.size(); ++it) show(v.at(ic));
--
どうでもいいが、C++なのだから変数のスコープはちゃんと意識して書くべきだ。
# 関数の先頭でループ制御変数を宣言するなんて恥ずかしいと知れ。
134デフォルトの名無しさん:2007/09/17(月) 09:17:05
>>132
普通に考えて、count という動詞が来たら結果は数だから。
empty なら bool だけど。
135デフォルトの名無しさん:2007/09/17(月) 09:26:39
>>130
for_eachの実装はこんな感じ

template <typename In, typename Fun>
Fun for_each(In first, In last, Fun f)
{
  for(In it = first; it != last; ++it)
    f(*first);
  return f;
}

fとしてshowが渡されるわけだから、showを呼ぶときの引数は*it。
itは引数として渡された区間を舐めるイテレータだから、
この場合mainのvの要素を順番に指すことになる。
136デフォルトの名無しさん:2007/09/17(月) 09:29:19
ああごめん、なぜ count があるかという問いだったか。
STL の標準版アルゴリズム群で map を操作するのは効率が悪いので、
map 専用版も用意することになった。同じアルゴリズムには同じ名前を
使いたいので count もそのまま残った、ということでしょう。
137デフォルトの名無しさん:2007/09/17(月) 10:13:47
>>128
配列の中身に0から9の値が順に格納されているから。
それを順に取り出して表示しているので、0から9の値が順に表示されるというだけ。
138128:2007/09/17(月) 14:38:18
for_eachの実装がわかってカラクリがわかりました
ありがとうございました
139デフォルトの名無しさん:2007/09/17(月) 16:06:52
STL はこれからも進化し続けるの?
もっと便利なコンテナも登場するの?
140デフォルトの名無しさん:2007/09/17(月) 16:19:21
つboost
とか言われるとboost厨uzeeとか言われるんだだろうなぁ
141デフォルトの名無しさん:2007/09/17(月) 16:47:53
C++0xスレに行ってくればいいんじゃね
念願のハッシュとかあるぜよ
142デフォルトの名無しさん:2007/09/17(月) 17:22:18
最近boost使い始めた
143デフォルトの名無しさん:2007/09/17(月) 18:20:14
std::stringを引数にとる関数の場合
スタックに積まれるのは文字列全部ですか?

144デフォルトの名無しさん:2007/09/17(月) 18:30:04
>>143
スタックにはクラス本体だけ。
文字列自体はヒープに確保される。
145デフォルトの名無しさん:2007/09/17(月) 19:28:52
>>139
C++0xでコンセプトが導入される予定なので
次期or次々期のSTLは全体的に書き換わるのではないかといわれている。
146デフォルトの名無しさん:2007/09/17(月) 19:31:11
コンセプトの導入をもって
HaskellはC++のサブセットになります
147デフォルトの名無しさん:2007/09/17(月) 19:39:09
それはないだろw
148デフォルトの名無しさん:2007/09/17(月) 21:55:12
>>144
じゃ、 const std::string& で引数をとるのはあんまり意味ないかな?
149デフォルトの名無しさん:2007/09/17(月) 22:04:35
いや、そのコピーコンストラクタでそのヒープの中身を
複製する実装も少なくない(下手したらこっちが主流かもしれない)だろうから、
依然としてconst参照にすべきだと思う。俺はそうしている。
150デフォルトの名無しさん:2007/09/17(月) 22:37:41
>>148
参照ならアドレス渡すだけだけど、値渡しなら、コピーコンストラクタが呼ばれるんじゃね?
文字列本体をヒープにもってて、参照カウンタをもってるような実装でも。
151デフォルトの名無しさん:2007/09/17(月) 22:46:58
>>148-150
コピーコンストラクタは文字通りコピーを作るんじゃないかな。(それが目的だと思っている)
だからconst参照を選ぶ。
152デフォルトの名無しさん:2007/09/18(火) 01:35:10
>>133
> どうでもいいが、C++なのだから変数のスコープはちゃんと意識して書くべきだ。

どうでもいいが、VC6だと変数のスコープがブロックの外になっちまうんだよな…
153デフォルトの名無しさん:2007/09/18(火) 01:55:12
>>152
いいえ。ブロックの外になることはありません。
154デフォルトの名無しさん:2007/09/18(火) 02:19:06
>>153
釣り?
155デフォルトの名無しさん:2007/09/18(火) 07:42:47
forの外はブロックの外とは言わない罠。
for (int i = 0; i < N; ++i) func(i);だったらそもそもブロックなんかないわけだし。
156デフォルトの名無しさん:2007/09/18(火) 09:45:57
規格厨、出番ですよ〜!
157デフォルトの名無しさん:2007/09/18(火) 09:51:55
>>153>>155
>>152の言わんとしている事に気づいてない様子だね
158デフォルトの名無しさん:2007/09/18(火) 09:56:21
むしろ双方気づいていて、>>155は揚げ足を取ってるだけ
159デフォルトの名無しさん:2007/09/18(火) 10:03:40
>>157-158
何に気づいてるって?
160デフォルトの名無しさん:2007/09/18(火) 10:13:10
>>159
>>152の言わんとしている事
161デフォルトの名無しさん:2007/09/18(火) 10:25:10
>>157-158
>>152の言わんとしている事って何?
162デフォルトの名無しさん:2007/09/18(火) 10:41:01
for(int i = 0; i < 9; i++) {}
cout << i; // ここでiが見えることだろ
163デフォルトの名無しさん:2007/09/18(火) 10:41:26
そうだね
164デフォルトの名無しさん:2007/09/18(火) 19:46:28
#define for if(0);else for
これで解決するかな?
165デフォルトの名無しさん:2007/09/18(火) 19:54:58
それif(1)forじゃだめなの?
166デフォルトの名無しさん:2007/09/18(火) 20:10:51
>>162
たまたま偶然見えてるように見えてるんじゃないの?

deleteやfreeで解放しても、しばらくは見えてるのと同じ理由だと思うの...
167デフォルトの名無しさん:2007/09/18(火) 20:28:20
>>165
それだと後ろにelse ifが続いたとき対応がおかしくなる。

>>166
ちがうよ。
VC6は本当にスコープが外れない。
168デフォルトの名無しさん:2007/09/18(火) 20:42:08
>>166
有効範囲(scope)と生存期間(extent)を区別しろよ。
構文的な有効範囲の外では名前自体が使えない(コンパイル時エラーになるべき)のであって、
寿命の尽きたオブジェクトを参照するのとは話が違う。
169デフォルトの名無しさん:2007/09/18(火) 21:08:53
>>164
それググったら出て来たやつだね
170デフォルトの名無しさん:2007/09/18(火) 21:53:03
>>155
>for (int i = 0; i < N; ++i) func(i);
これって「暗黙のブロック」みたいな言い方しないっけ?

>>152
>>162の様なソースの外側のブロックでiが別の定義されてないか?
171デフォルトの名無しさん:2007/09/18(火) 22:22:35
されてない場合で言ってるんだよ
172デフォルトの名無しさん:2007/09/18(火) 22:22:50
>>170
言う。
けど、for内で宣言した変数が162のように外側でも見えるVC++ 6やARMだと、
forは暗黙のブロックを作らないのではないのかと思う。
そして、ISO C++ではforも暗黙のブロックを作る対象になっている (§6.4)。
(確かめたのはJIS X3014なんだけどさ)
ARMは今手元にないからわからない。
173デフォルトの名無しさん:2007/09/18(火) 22:38:27
forのスコープを標準に準拠させられるのはVC7からだっけ?
VC8からはデフォルトで7.1はオプションだったのは覚えてる
174デフォルトの名無しさん:2007/09/18(火) 22:44:56
VC6でも/ZaでMS独自拡張を切るとforもISO C++どおりになるが、
標準ライブラリもまともに使えないと聞いたことがある。
自分で試したのではないけど。
175デフォルトの名無しさん:2007/09/18(火) 23:22:33
つまりこういうこと?
#include <stdio.h>

void main()
{
for( int i = 0; i < 10 ; i++ )
printf( "%d", i );

for( int i = 0; i < 10 ; i++ ) //2重定義でエラーの出るコンパイラがある
printf( "%d", 10 - i );
}
176デフォルトの名無しさん:2007/09/18(火) 23:32:02
>>175
そそ。VC6だとエラーになる。
177デフォルトの名無しさん:2007/09/19(水) 02:11:25
初めてSTL使ってみた初心者です。
配列の大きさ気にしなくていいので楽ですね。
便利な関数もいろいろあって役に立ちそうです。
なにを今さらなことなんですけどw
178デフォルトの名無しさん:2007/09/19(水) 02:53:37
コンテナが便利とか言っているうちは素人。
ファンクタ関連の貧弱さに怒れるようになって初めて一人前。

精進せい。
179デフォルトの名無しさん:2007/09/19(水) 03:18:06
いいんじゃね
最初はvectorだけ使うとかで

そのうち色んな順番でソートしたいとか連想配列使いたいとか欲求がでてきて
>>178
になってboostへ
180デフォルトの名無しさん:2007/09/19(水) 04:53:54
shared_ptrが使いたいが為にboostを使い始めて、
今ではどっぷり浸かってます。
181デフォルトの名無しさん:2007/09/19(水) 07:58:34
テンプレートメタプログラミング厨はどこに行き着きますか?
182デフォルトの名無しさん:2007/09/19(水) 09:20:40
1. テンプレートの書きにくさに絶望します。
2. 関数型言語を知って狂喜します。
3. コンパイル時計算が書けないことに絶望します。
4. Lispのマクロを知って狂喜します。
5. 型をベースにした計算ができないことに絶望します。
6. もう逃げ場がないので、自ら命を絶ちます。
183デフォルトの名無しさん:2007/09/19(水) 10:57:58
そこで俺様言語開発
184デフォルトの名無しさん:2007/09/19(水) 12:27:17
コンパイル時に型付き計算できるC++マクロを開発すりゃいくね?
185デフォルトの名無しさん:2007/09/19(水) 13:50:49
C++では何をするにも複雑すぎる
Dも既に十分すぎるぐらいに複雑な変態言語だが、それでもC++よりはずっと簡潔に
コンパイル時計算が出来る

template factorial(int n)
{
static if (n == 1)
const factorial = 1;
else
const factorial = n * factorial!(n-1);
}
186デフォルトの名無しさん:2007/09/19(水) 15:11:36
逆に考えるんだ。宣言的マッチを強制するC++の方がモダンだと。
187デフォルトの名無しさん:2007/09/19(水) 19:07:06
モダンって今時言わないよw
ナウだね。ナウい。
188デフォルトの名無しさん:2007/09/19(水) 19:19:19
ナウい C++ デザイン

あんどりゅ・あれきさんどれすく
189デフォルトの名無しさん:2007/09/20(木) 00:08:36
STLよりboostを使うほうがベター?
190デフォルトの名無しさん:2007/09/20(木) 00:22:13
ほとんどはお互いを補完しあう存在なので、どっちがベターと言えるものではない。

std::bind1st類とboost::bindといった具合に、
機能が完全に重複することは、ないわけではないが稀。
ただし、こういう場合は間違いなくBoostのほうがベター。
191デフォルトの名無しさん:2007/09/20(木) 00:50:11
コンパイルにかかる時間は増えるけどな
192デフォルトの名無しさん:2007/09/20(木) 07:54:50
コンパイラがもっと最適化されればいいんだ
193デフォルトの名無しさん:2007/09/20(木) 13:23:19
ovenとか使わせてもらっててクリーンビルドに30分ぐらいかかるけどあまり気にならないよ
その間別の事すればいいだけだし
プリコンパイルヘッダ使えばその時間も短縮される
194デフォルトの名無しさん:2007/09/20(木) 14:03:01
作成中はコンパイル最適化しないほうがいいよ
STLとかコンパイル断然速くなるよ
195デフォルトの名無しさん:2007/09/20(木) 21:57:50
「作成中」の真意が分かりかねるが、
デバッグビルドで最適化しないのは当然だろ。
196デフォルトの名無しさん:2007/09/20(木) 22:10:32
Qtしか使った事がないので、QValueVector QPtrVector 等しか使った
事がありませんが、STL と比べるとどうなんでしょうか?

全部読んでないのですが、皆さんはテンプレート機能を使って、
新規にテンプレートクラスを制作しているのでしょうか?
197デフォルトの名無しさん:2007/09/21(金) 09:23:50
テンプレートだけならそんなに敷居は高くないが、
ファンクタやら独自コンテナやらを自分で書ける奴は多くなさそうだ。
198デフォルトの名無しさん:2007/09/21(金) 10:31:53
コンテナに投入するクラスって、
デフォルトコンストラクタがなければだめなんですよね?
199デフォルトの名無しさん:2007/09/21(金) 10:37:16
push_backやassignにインスタンスを渡すならコピーコンストラクタとかコピー代入オペレータも必要になるかも
200デフォルトの名無しさん:2007/09/21(金) 11:22:51
>>198
サイズ指定のみのコンストラクタ、サイズ指定のみの resize() 、 map の operator [] () の
どれも使わないのであれば必要ない。

むしろコピーコンストラクタとコピー代入演算子のほうが広く必要とされる。
201デフォルトの名無しさん:2007/09/21(金) 16:25:08
>>200
なるほど。
○○のコンテナに入れるなら、あるいは○○の機能を使うなら
○○を満たしていなければならない、みたいな取り決めを知るには
やっぱり正式な仕様書を読まなければなりませんか?
今のところコンパイラが出すわかりにくいテンプレートがらみの
エラーメッセージ見ながら、「う〜ん、このテンプレートで
エラーが出てるんだからこれができなくって怒られてるんだろうなぁ」
とか推測しながらやってます。
202デフォルトの名無しさん:2007/09/21(金) 17:04:02
>>201
今はそうするしかない(将来的にはソース上に書き下せるようになりそう)。
テンプレート引数に要求される事柄は、
一般にコンセプト (concept)とか要件 (requirement)と呼ばれる。

C++の規格書であるJIS X 3014は、ttp://www.jisc.go.jpで見れる
203デフォルトの名無しさん:2007/09/22(土) 13:02:40
閲覧出来るけど印刷不可かあ。
204デフォルトの名無しさん:2007/09/22(土) 13:07:21
つ PrintScreen
205デフォルトの名無しさん:2007/09/22(土) 14:35:26
つ[キャッシュ]
206デフォルトの名無しさん:2007/09/22(土) 15:06:18
つ 通報
207デフォルトの名無しさん:2007/09/22(土) 18:23:01
全部ポインタにすれば解決
208デフォルトの名無しさん:2007/09/22(土) 22:25:05
いつも思うんだけど、何でこんなにJISはケチ臭いのか
言語を普及させるつもりないのかな
209デフォルトの名無しさん:2007/09/22(土) 22:33:48
はい
210デフォルトの名無しさん:2007/09/22(土) 23:01:02
>>208
言語をというより、規格全般じゃない?
211デフォルトの名無しさん:2007/09/22(土) 23:43:33
ISOなんか金払わなきゃ落とせないんだからJISのが全然良心的
212デフォルトの名無しさん:2007/09/23(日) 01:04:23
ISO のほうならドラフトがダウンロードできるから助かる。
213デフォルトの名無しさん:2007/09/23(日) 04:38:55
ISOはeMuleかtorrentで(ry
214デフォルトの名無しさん:2007/09/23(日) 08:20:53
JISって公的資金に頼ってるんじゃないの?
完全に独立採算な団体なの?
215デフォルトの名無しさん:2007/09/23(日) 08:28:01
半官半民じゃね?
216デフォルトの名無しさん:2007/10/02(火) 08:30:45
STLのlistってオブジェクトがなくなったとき
コンテナの中身も削除してくれますか?
217デフォルトの名無しさん:2007/10/02(火) 08:31:52
コンテナの中身「は」削除してくれます
218デフォルトの名無しさん:2007/10/02(火) 08:41:26
ということは、コンテナの中身がポイントしているオブジェクトは削除されないんですね?
219デフォルトの名無しさん:2007/10/02(火) 08:43:55
そうです
スマートポインタを使いましょう
220デフォルトの名無しさん:2007/10/02(火) 09:11:55
new するようなケースは大体全てにスマートポインタ使うべきでしょうか?
221デフォルトの名無しさん:2007/10/02(火) 09:30:05
スマートポインタの使用のコスト(一般的に生ポインタより遅く容量を食う)が問題にならない場合は使うべきです
コンテナに使用する場合は全適用しちゃっていいでしょう
ただしstd::auto_ptrはリソースを共有する際問題になることがあるので控えましょう
effective C++第三版の3章にわかりやすい説明がありますのでそこを読むと良い解が得られるかもしれません
222デフォルトの名無しさん:2007/10/02(火) 09:36:09
結局のところお前らBoostをどう思ってるの?
223デフォルトの名無しさん:2007/10/02(火) 09:42:33
ブスっと見つめる
224デフォルトの名無しさん:2007/10/02(火) 09:45:43
>>222
無いと困る。
serialization とか shared_ptr とか特に。
225デフォルトの名無しさん:2007/10/02(火) 09:54:19
preprocessorとかmplとか特に
226デフォルトの名無しさん:2007/10/02(火) 10:12:38
次のバージョンがすごすぎて
ほんとにリリースできるのか不安になる
227デフォルトの名無しさん:2007/10/02(火) 11:05:01
>>226
STL の話? Boost の話?
228デフォルトの名無しさん:2007/10/02(火) 11:05:48
0xの話でも意味が通じるw
229デフォルトの名無しさん:2007/10/02(火) 17:56:06
コンテナに突っ込む前にコンセプトチェックしようと思うんだけど、
どうすればいいの?コンセプトチェックは boost::concept_check
使うとして、どのコンテナに入れるにはどのコンセプトを満たして
いなければならないってのはどこにリストがあるの?

SGI のドキュメント嫁?
230デフォルトの名無しさん:2007/10/02(火) 18:11:44
231デフォルトの名無しさん:2007/10/02(火) 18:34:16
複数の入力ファイルを渡したいとき、
いっぱい std::ifstream 開いておいて

foo (std::vector<std::istream>& streams) {
   .....
}

みたいにして渡すのは邪道?そもそもストリーム自体を
コピーしたりしていいんだろうか、という疑問もある。
232デフォルトの名無しさん:2007/10/02(火) 18:40:47
TR2まだあ?
233231:2007/10/02(火) 18:43:18
バカなこと考えずに
std::vector<boost::shared_ptr<std::istream>>
渡すことにしました。
234デフォルトの名無しさん:2007/10/02(火) 18:49:40
>>231
残念ながら、std::istreamは
AssignableでもCopyConstractableでもないので複製できない。
235デフォルトの名無しさん:2007/10/07(日) 14:01:18
ifstream複製しようとする奴はじめて見た
236デフォルトの名無しさん:2007/10/07(日) 15:28:44
前にも見たことあるけど

FILE*のようにストリームを変数に入れておこうという考えを
持つのはごく自然なことで、
std::streamがコピー可能であることを知らない初心者がはまる
ありがちな罠なんじゃないの
237デフォルトの名無しさん:2007/10/07(日) 17:41:35
>>236
だからコピー可能ではないと思うのだが。
238デフォルトの名無しさん:2007/10/07(日) 19:17:54
たぶん
「コピー不可能であることを」
のタイポかな
239デフォルトの名無しさん:2007/10/07(日) 19:25:08
ああそのとおり、すまんねtypoだ
240デフォルトの名無しさん:2007/10/08(月) 03:43:31
質問です。 map< int , string > とした場合、要素側stringの検索は
foreachするしかないでしょうか?
241デフォルトの名無しさん:2007/10/08(月) 03:48:46
>>240
map< string , map::iterator > という手もあるかもね。
242デフォルトの名無しさん:2007/10/08(月) 03:49:50
>>241
kwsk
243デフォルトの名無しさん:2007/10/08(月) 03:51:45
>>242
string をキーとした検索用の map を追加で用意するってこと。
もちろん更新は必ず同時に行う必要があるから、それらを包むクラスを
作ることになる。

面倒だから、検索速度に不満がなければループまわして探しとけ。
244240:2007/10/08(月) 04:04:12
>>241
早速にありがとうございます。

int key = hoge["hogehoge"]->first;

ということですね。 やはり専用関数は無いも
のなんですね。(重複とか面倒そうですもんね)

map2本立てで検討したいと思います。
245デフォルトの名無しさん:2007/10/08(月) 14:06:53
>>244
boost::multi_index_container
246デフォルトの名無しさん:2007/10/08(月) 17:04:56
テンプレートを使い始めたら、分割コンパイルで、リンクする際にエラーが出るようになってしまいました。
分割しなければ問題ありません。非常に単純なプログラムでも、テンプレートがあるだけで、
リンクに失敗します。対処方法を教えてください。
247デフォルトの名無しさん:2007/10/08(月) 17:18:25
クラス・関数テンプレートは全てヘッダに書く。
248デフォルトの名無しさん:2007/10/08(月) 17:18:48
エスパー様、とちゃんと宛先を書け。
または、現象を再現させる最小のコードを貼れ。
249デフォルトの名無しさん:2007/10/08(月) 18:12:31
つExceptional C++ Style : 9. キーワードexportの制限
250デフォルトの名無しさん:2007/10/08(月) 20:48:27
exportがまともに動作するコンパイラってあるの?
251デフォルトの名無しさん:2007/10/08(月) 20:50:42
そんな予約語はなかった
252デフォルトの名無しさん:2007/10/08(月) 21:08:18
コメアウ >>250
253デフォルトの名無しさん:2007/10/11(木) 01:44:40
初心者なんだけど
list使ってみたら添え字でアクセスできないのが
思った以上に不便に感じた('A`)
254デフォルトの名無しさん:2007/10/11(木) 01:49:42
list は連結リストだから、添え字アクセスなんか仮に出来ても遅いぞ
vector 使っとけ
255デフォルトの名無しさん:2007/10/11(木) 01:50:30
おうvectorマンセー!!
256デフォルトの名無しさん:2007/10/11(木) 02:07:18
vector はメモリアロケート対策に何も考えないと指数的にメモリを喰うぞ
list に要素本体格納して vector にそれへのポインタ入れとけ
257デフォルトの名無しさん:2007/10/11(木) 02:10:24
え?
258デフォルトの名無しさん:2007/10/11(木) 02:12:40
                    ,.へ    ___,.へ
               __,,. --─'──`<.,,/:::::::ト、
            ,. '"            `'く:::::::ト.
    ∧      /  ゝ____,.へ--、へr-、ノ   i、::::! | /!
    V      i__,.へ!_,./--'─'--'-<ヽi__/ Y | /」
   __i.     r'へ,.イ   /  ハ  ハ i  `ヽ7、.| .|/
 ∠__,.ヘ     `Y´ / / ハ__/,.ィ レ' レヘ、_!_ i iヘ| |<>
    /iヽ.     i イハ /i rr--'テ    ,r-テiレヘ i | |  
   !/  !.,    |   V :| ゞ-'    ヽ' ハ ハノ| |> いくらこのスレでも許容限度があると思う。
      ∧ `ヽ、ノ  〈 ハ "         "从ヽレi. |
      V  /!〈rヘハ!|`ヽ、.,_  ´ _,,.イハ ハ〉 レ'
         |/ / レ/´ ̄`ヽニ7´ト、!/ Vヽ>
            !/〈    `ヽムi  i/
               ヽ_r、_イヘノハi_,.r〉
               i:::ヘ  ',:::::/ /
             ,.rく::/::ハ  ヽ7 /ト、
            ,r<:::::::ヽ::〉  i/イ_:::\、
           ri  ´ ̄ ̄7 ̄7'^ヽ'ヽ. `iヽ、
          くL!、.,______,,.l____i,  i  i_ノ_ノ::>
                   ヽ-'^ー'  ̄
259デフォルトの名無しさん:2007/10/11(木) 19:52:31
なんというテンプレ候補
260デフォルトの名無しさん:2007/10/12(金) 00:34:36
添え字でアクセスできるリストってないの?
261デフォルトの名無しさん:2007/10/12(金) 00:38:46
そんなlist構造の存在意義を否定するようなもの、STLにはない。
262デフォルトの名無しさん:2007/10/12(金) 00:44:40
別にランダムアクセスが遅いことがリスト構造の存在意義じゃないだろ。
実際、双方向リストを拡張してランダムアクセスに比較的強いデータ構造を作ることもできるはずだし。
STLにはないけど。
263デフォルトの名無しさん:2007/10/12(金) 00:52:14
boostにあるmulti_index_containerがその要求に応えてくれる筈
264デフォルトの名無しさん:2007/10/12(金) 03:02:35
[]演算子を自分で定義すればできるよ!できるよ!
265デフォルトの名無しさん:2007/10/12(金) 03:34:16
std::map<int, hoge>
266デフォルトの名無しさん:2007/10/12(金) 07:26:28
その場合のhashがlist構造になることは保証されているのでしょうか?
267デフォルトの名無しさん:2007/10/12(金) 07:44:20
STLにはhashがありません。
268デフォルトの名無しさん:2007/10/12(金) 08:16:42
STLって、実装は規定しないんじゃなかったか?
両進イテレータでアクセスできるとか、
最悪でも線形時間で処理が終わるとか
そういう言い方で規定してるような。
だから、内部的にhashを持つlist実装も不可ではないはずだ。
常識的にはtreeで実装するがな
269デフォルトの名無しさん:2007/10/12(金) 08:48:44
現状O(1)で済む処理がO(1)にならなくなったり
iterateしながらの挿入削除といった操作に対して弱くなりそうだが
270デフォルトの名無しさん:2007/10/12(金) 10:53:23
>>268
map はソート済みシーケンスになる必要があるから、ハッシュは使えないと思う。
271デフォルトの名無しさん:2007/10/12(金) 11:44:11
任意の型のキーに対してハッシュ値を計算できないだろう
ユーザが勝手に作ったクラスとかどうするんだ
272デフォルトの名無しさん:2007/10/12(金) 11:47:19
はいはーい
hash計算関数を書かせればいいと思いまーす
273デフォルトの名無しさん:2007/10/12(金) 11:54:52
>>271
それは std::map に

任意の型のキーに対して比較演算できないだろう
ユーザが勝手に作ったクラスとかどうするんだ

って言うようなもんだぜ。
274デフォルトの名無しさん:2007/10/12(金) 12:12:17
>>273
std::map はコンストラクタで比較用の関数オブジェクトを指定する仕様だから、それを使うに決まっている
275デフォルトの名無しさん:2007/10/12(金) 12:26:28
ADLを利用してoperator>を定義してやるだけでおkじゃなかったっけ
276デフォルトの名無しさん:2007/10/12(金) 12:46:03
デフォルト引数で std::less<Key> が指定されてるから、デフォルトのまま使う場合は operator< でおk
277273:2007/10/12(金) 12:56:43
>>274-276
それは知ってる。
hash 関数も同じようにできるから >>271 はおかしいって話。

デフォルトの less みたいなのが決められないってのが、かつて
規格に含まれなかった理由かな?
278デフォルトの名無しさん:2007/10/12(金) 20:18:46
std::map<int, hoge>

keyがintでもhash値計算し直すの?
279デフォルトの名無しさん:2007/10/12(金) 23:05:18
unorderd_mapの実装だとどうなってる?
280デフォルトの名無しさん:2007/10/13(土) 01:48:37
>>279
クラステンプレート std::hash が標準で提供されて、デフォルトだとそれ使う。

20.5.15 Class template hash [unord.hash]
1 The unordered associative containers defined in clause 23.4 use specializations of hash as the default hash function.
This class template is only required to be instantiable for integer types (3.9.1), floating point types (3.9.1), pointer
types (8.3.1), and std::string, std::u16string, std::u32string, and std::wstring.
281デフォルトの名無しさん:2007/10/13(土) 12:31:55
どんなクラスでも挽き肉にしちまえば同じ型?
282デフォルトの名無しさん:2007/10/13(土) 13:40:55
std::hash の戻り値は sttd::size_t 。
283デフォルトの名無しさん:2007/10/13(土) 15:57:43
実態はメモリ上に格納するから、size_tってのは妥当だな。
284デフォルトの名無しさん:2007/10/13(土) 15:59:49
std::size_tを使うと
intの値に変換するときにコンパイラに怒られるのが嫌
285デフォルトの名無しさん:2007/10/13(土) 16:07:40
>>284
そういう使い方して良いのかな?
わざわざ怒られるくらいだからしない方が良い?
286デフォルトの名無しさん:2007/10/13(土) 16:10:58
でも外部のライブラリなんかがintを要求するのはよくあること。
287デフォルトの名無しさん:2007/10/13(土) 16:32:53
ま、外部のライブラリが時代遅れっつうことで我慢だ
コンパイラに怒られることが問題なんじゃあない
288デフォルトの名無しさん:2007/10/13(土) 18:41:30
怒られるのが嫌なら明示的にキャストすればいい
289デフォルトの名無しさん:2007/10/13(土) 18:51:00
Cスタイルのキャストはあまり使いたくないんだがこういう時ぐらいは許してもらえるかな…
290デフォルトの名無しさん:2007/10/13(土) 18:53:54
>>289
static_cast で十分だろ。許さない。
291デフォルトの名無しさん:2007/10/13(土) 19:28:26
ライブラリによっては非constポインタを要求してくるから、
static_castだけでは不十分だ。
292デフォルトの名無しさん:2007/10/13(土) 19:31:55
>>291
いつの間にポインタの話に・・・まあいいけど。

可能ならローカルなコピーを渡せ。それがダメなら const_cast しろ。
Cスタイルキャストは許さない。
293291:2007/10/13(土) 19:33:43
>>292
ごめん、286が「外部のライブラリ」とか言ってるから
ライブラリにデータを渡す際に必要になるキャスト全般の話をしているのかと…
294デフォルトの名無しさん:2007/10/13(土) 20:14:04
関数型キャストは……ポインタには使えないか。
295デフォルトの名無しさん:2007/10/13(土) 20:29:14
unionでおk
296デフォルトの名無しさん:2007/10/13(土) 21:07:04
reinterpret_cast + const_castコンボとかだと流石にげんなりするな
297デフォルトの名無しさん:2007/10/14(日) 01:32:05
イテレータの名前をいつも迷うんだけど
みんなはどういう名前にしてる?
298デフォルトの名無しさん:2007/10/14(日) 01:33:42
i j k
299デフォルトの名無しさん:2007/10/14(日) 01:33:45
面倒なんでBOOST_TYPEOFを使っちゃってます
300デフォルトの名無しさん:2007/10/14(日) 01:55:29
it,jt,ktの俺は異端
301デフォルトの名無しさん:2007/10/14(日) 01:59:47
俺は iterator i, iterator j, iterator k という風に心の中で読んでおいて、その実体は ii, ij, ik
でも k までネスト構造を作るのは気持ち悪いから実際には j までしか行かないな、関係ないけど。
302デフォルトの名無しさん:2007/10/14(日) 02:18:12
リストのときはit_l
ベクタのときはit_v
ってやってた
303デフォルトの名無しさん:2007/10/14(日) 02:20:51
>>297
変数名は使用目的に合わせてつけろよ。型じゃなくてさ。
単純なループ用なら int i, j, k, ... でいいけど。
304デフォルトの名無しさん:2007/10/14(日) 03:30:04
>>297
もちろん
iterator
305デフォルトの名無しさん:2007/10/14(日) 04:07:50
itereetaa
306デフォルトの名無しさん:2007/10/14(日) 04:51:21
>>299
イテレータはたいてい登録できないぞ
307デフォルトの名無しさん:2007/10/14(日) 05:48:34
native typeofだと登録なしで使えるってその登録じゃないか
308デフォルトの名無しさん:2007/10/14(日) 17:51:06
とあるクラスfooへのポインタを格納するリストのmylistがあるとします。
このリストから、foo::isInvalidがTRUEの要素だけを削除したいと思います。
次のように実装してみたのですが、クラッシュしてしまいます。

std::list<foo*>::iterator it;
for(it = mylist.begin() ; it != mylist.end() ; ++it)
{
 foo * p = (foo *)(*it);
 if(p->isInvalid)
 {
  mylist.erase(it);
  delete p;
  continue;
 }
}

そこでmylist.erase()したら、itをmylist.begin()で初期化するようにしたところ
クラッシュしなくなりました。

もしかしてリストから要素をeraseすると、イテレータは無効になるのでしょうか?
309デフォルトの名無しさん:2007/10/14(日) 17:54:22
erase()の戻りがiteratorなのはなんでだと思う?
310デフォルトの名無しさん:2007/10/14(日) 17:57:47
>>308
> もしかしてリストから要素をeraseすると、イテレータは無効になるのでしょうか?

あたりまえだろ。
311デフォルトの名無しさん:2007/10/14(日) 17:59:18
>>309-310
あ、なるほど。。戻り値が新しい有効なイテレータなんですね。。
勉強になりました。ありがとうございます。
312デフォルトの名無しさん:2007/10/14(日) 18:00:59
>>308
std::list::remove_if() 使えば?
これぐらいなら標準のファンクタでいけるだろ。
313312:2007/10/14(日) 18:01:46
あ、ごめん。 delete p が要るのか。標準のやつだけじゃ面倒だな。
314デフォルトの名無しさん:2007/10/14(日) 18:02:23
> itをmylist.begin()で初期化

典型的O(n^2)処理にワロタ
315308:2007/10/14(日) 18:02:41
308です。するとこんな風に書けばいいのでしょうか?
std::list<foo*>::iterator it;
for(it = mylist.begin() ; it != mylist.end() ; ++it)
{
 foo * p = (foo *)(*it);
 if(p->isInvalid)
 {
  it = mylist.erase(it);
  delete p;
  if(it == mylist.end())
  {
   break;
  }
 }
}

みなさんならどうしますか?
316デフォルトの名無しさん:2007/10/14(日) 18:02:54
>>308
> foo * p = (foo *)(*it);

こういうキャストやめてくれよ。
317デフォルトの名無しさん:2007/10/14(日) 18:03:23
サ、サイズが1なら問題ないもん!
318デフォルトの名無しさん:2007/10/14(日) 18:18:56
>>315
なんでキャストが要るんだ?

まぁそれでいいと思うが、俺ならstd::list<boost::shared_ptr<foo> > にしてdeleteはしないな。
319デフォルトの名無しさん:2007/10/14(日) 18:22:45
>>308
for(std::list<foo*>::iterator it = mylist.begin();
  it != mylist.end();)
{
 foo * p = *it;
 if(p->isInvalid) {
  mylist.erase(it++);
  delete p;
 } else {
  it++;
 }
}
これでどうよ。eraseがiteratorを返さないコンテナでもOK。
320デフォルトの名無しさん:2007/10/14(日) 18:22:58
>>315
それだとinvalidなのが連続したときに二番目を逃すことになる
eraseしなかったときだけ++itするべし
321デフォルトの名無しさん:2007/10/14(日) 18:24:58
>>317 どこの誤爆?
322デフォルトの名無しさん:2007/10/14(日) 18:28:15
>>321
たぶん>>314へのレスじゃね?
323デフォルトの名無しさん:2007/10/14(日) 18:28:47
>>319
なるほど。僕もそれで行くことにします。

>>320
あ、そうですね。。忘れてました。。

>>316
そうですよね。。でもそうしないとインテリセンスが反応してくれないのでつい。。


皆さんありがとうございました(^-^)
324デフォルトの名無しさん:2007/10/14(日) 18:52:39
>>319
それvectorに適用しようとするとひどいことになるぞ
325デフォルトの名無しさん:2007/10/14(日) 19:04:12
vectorの真ん中をeraseする奴なんているのか?
326デフォルトの名無しさん:2007/10/14(日) 19:13:37
別におかしくないだろ
327デフォルトの名無しさん:2007/10/14(日) 20:09:12
vectorなんてクソ vectorなんてクソ vectorなんてクソ
328デフォルトの名無しさん:2007/10/15(月) 00:58:16
STLって流行ってる?
うちの職場だと使ってるやつ数人だよ
存在も知らないやつも多い気がする
うちがレベル低いだけですかそうですか
329デフォルトの名無しさん:2007/10/15(月) 00:59:22
わかってるじゃない。
330デフォルトの名無しさん:2007/10/15(月) 01:00:57
レベル低い
331デフォルトの名無しさん:2007/10/15(月) 02:51:47
>>328
もう流行るとかいう段階を越えて、常識と化している。
・・・はずなんだけど、そういう職場の例はしょっちゅう出てくるね。
332デフォルトの名無しさん:2007/10/15(月) 03:10:34
流行る 流行らない という性質のものじゃない気が
333デフォルトの名無しさん:2007/10/15(月) 06:34:32
>>297
iter
ite
it
i
ネストが深くなるにつれて名前が短くなる
334デフォルトの名無しさん:2007/10/15(月) 07:02:14
itr
itr_end

itr_i
itr_j
itr_k
....
の俺は少数派ですか?
335デフォルトの名無しさん:2007/10/15(月) 09:08:57
>>333
4段以上のときはどうするの?
逆にした方が文字数でネストの深さがすぐに分かって良いかもね
336デフォルトの名無しさん:2007/10/15(月) 19:02:32
iteratoooooor
337デフォルトの名無しさん:2007/10/16(火) 01:41:08
Effective STLって役立つね
読んでるやついる?
つーか常識?
338デフォルトの名無しさん:2007/10/16(火) 02:55:51
workaround的なものが多くてなんだかなーって
339デフォルトの名無しさん:2007/10/16(火) 09:28:04
stl::listのpop_front()について質問です。
double_freeで落ちてしまったので、いろいろ調べ始めたのですが
要素数がないときはどのような動作をするものなのでしょうか?
環境によって動作が変わったりするものなのでしょうか?

要素数チェックを含んでいるかどうかを調べようと思ったのですが
これといったドキュメントを見つけられませんでした。
340デフォルトの名無しさん:2007/10/16(火) 09:54:48
規格にはa.pop_front()はa.erase(a.begin())と同じだと定義されている。
で、eraseについては、「有効な」イテレータqに対して、a.erase(q)の意味が定められてる。
aが空の時はa.begin()は有効なイテレータを返さないから、a.pop_front()の意味は規定されてないことになる。
341デフォルトの名無しさん:2007/10/16(火) 10:09:38
やはりキチンと要素数チェックをすべきということですね。
ありがとうございました。
342デフォルトの名無しさん:2007/10/17(水) 12:57:49
std::string で reserve() メソッドを呼び出したとき,
要求したメモリを確保できなければ例外が発生するのですか?
343デフォルトの名無しさん:2007/10/17(水) 13:31:15
>>342 はい。
344デフォルトの名無しさん:2007/10/17(水) 13:38:32
>>343
すんまそん、なんつー例外が発生するんでしょうか?
std::runtime_error の派生クラスだと思うんですが・・
345デフォルトの名無しさん:2007/10/17(水) 13:43:22
>>344 std::bad_alloc
346デフォルトの名無しさん:2007/10/17(水) 18:24:25
valarrayにswapとassignはないの?
347デフォルトの名無しさん:2007/10/17(水) 18:52:13
valarrayはSTLじゃない
348デフォルトの名無しさん:2007/10/17(水) 20:29:42
valarrayとbitsetは見なかったという事でひとつ・・
349デフォルトの名無しさん:2007/10/17(水) 21:04:31
でもvector<bool>はSTLだよね…
350デフォルトの名無しさん:2007/10/17(水) 21:28:21
コンテナかどうか議論するならまだしもSTLではないと言うのは意味不明
351デフォルトの名無しさん:2007/10/17(水) 22:09:25
vector<bool>はSTLのコンテナの要件を満たしてないけどね
352デフォルトの名無しさん:2007/10/17(水) 22:13:52
vector<bool>特殊化はいつ抹殺されるの?
353デフォルトの名無しさん:2007/10/17(水) 23:12:37
このスレの名前自体が以下略
354デフォルトの名無しさん:2007/10/17(水) 23:18:06
いや、C++の標準ライブラリの一部を漠然と括るには便利な名前じゃん
明確な定義がない以上どこまでがSTLかの境界を定めようとするのが不毛ってだけで
355デフォルトの名無しさん:2007/10/17(水) 23:39:59
使うと初心者離れしたような錯覚を起こす例のライブラリ群
だよね!
356デフォルトの名無しさん:2007/10/17(水) 23:40:26
boostのことか
357デフォルトの名無しさん:2007/10/17(水) 23:46:03
まあ、boostも着々と標準に取り込まれつつあるようだし
いずれboostがSTLの範疇になるの日がくる……かも
358デフォルトの名無しさん:2007/10/17(水) 23:50:38
標準ライブラリって作られたときは歴史が浅いからマズイ仕様がおおいよな。
359デフォルトの名無しさん:2007/10/18(木) 00:07:33
boostは敷居が高すぎるな
エラーが出ると何がなんだかさっぱり解らん
360デフォルトの名無しさん:2007/10/18(木) 00:23:14
凝りすぎのライブラリは大抵糞
361デフォルトの名無しさん:2007/10/18(木) 00:38:32
boostヘッダが長くて萎える
362デフォルトの名無しさん:2007/10/18(木) 00:56:04
初心者だけどboost使ってすみません
でもboostからC++に入ったのでやめられません
363デフォルトの名無しさん:2007/10/18(木) 02:14:31
道具なんだから使いたいときに使えばいいだけ
364デフォルトの名無しさん:2007/10/18(木) 02:28:38
美人は三日で飽きる
Boostは三日で慣れる
365デフォルトの名無しさん:2007/10/18(木) 09:03:36
bootsは三日で臭くなる
366デフォルトの名無しさん:2007/10/18(木) 09:16:49
>>365
bootsスレに行け。
367デフォルトの名無しさん:2007/10/18(木) 15:24:27
valarray … MTLとかのライブラリの登場でお払い箱 …
bitset … 何それ?(固定長ならビットフィールドで十分)
368デフォルトの名無しさん:2007/10/18(木) 16:02:07
>>367
C++0xの新機能を使って書き直して
リニューアル/パワーアップするとかないのかな…
369デフォルトの名無しさん:2007/10/18(木) 21:01:43
ないでしょう。valarrayはインターフェースがダメ
370デフォルトの名無しさん:2007/10/21(日) 05:19:09
VC80のmapのメモリ配置がvectorみたいに連続しているんですが、
やはりvectorがそうであるように挿入を繰り返すと大量の領域があらかじめ確保されてしまうんでしょうか。
1万件を超える数の要素を操作するから利用を躊躇う。
371デフォルトの名無しさん:2007/10/21(日) 07:02:12
連続してたらmapの意味無いじゃん
372デフォルトの名無しさん:2007/10/21(日) 10:39:55
>>370
想像で「躊躇う」とか言ってないで、自分のケースで実際にまずいかどうかは
実測して判断したら?
まずいようなら、Berkeley DBのようなものを使えばいいでしょ
373デフォルトの名無しさん:2007/10/21(日) 17:41:48
vector<int> result;
resultを戻り値にしたいのですが、プロトタイプは、どのように宣言したらいいですか
374デフォルトの名無しさん:2007/10/21(日) 17:48:41
日本語でok >>373

vector<int> foo();

375デフォルトの名無しさん:2007/10/21(日) 17:52:38
>C++標準ライブラリの一つ
とあるけど、ほかの標準ライブラリってたとえば何があるの?
376デフォルトの名無しさん:2007/10/21(日) 17:55:46
>>375 Cから引き継いだライブラリとかじゃね?
377デフォルトの名無しさん:2007/10/21(日) 18:00:00
>>376
広い意味ではC++のライブラリに含めるかもだけど
普通はCのライブラリだから 標準とはちっと違う気がします
378デフォルトの名無しさん:2007/10/21(日) 18:06:46
>>374
日本語理解してくれてありがd
ほんまやね、適当に関数定義と宣言してもコンパイラ通りますやん
vector<int> foo();
vector<int> foo()
{
  vector<int> result;
return result;
}
379デフォルトの名無しさん:2007/10/21(日) 18:10:39
>>378
なにが疑問なのかさっぱりわからんが、コピーを戻していることを忘れるなよ。

vector<int>* foo();
とか
boost::shared_ptr<vector<int> > foo();
とできないか、よく考えとけ。
380デフォルトの名無しさん:2007/10/21(日) 18:10:48
>>375

IOストリームはSTLじゃない。stringもSTLコンテナとして使えるがSTLではない。
C++固有のライブラリならこのくらいかな…?
標準例外クラスもかな?
381デフォルトの名無しさん:2007/10/21(日) 18:21:11
なんで>>379は切れ気味なんだろうかww
382デフォルトの名無しさん:2007/10/21(日) 18:25:39
delete reinterpret_cast<std::vector<int>*>(>>381);
383デフォルトの名無しさん:2007/10/21(日) 18:27:21
これくらいで切れ気味って認識なら完全に切れてるやつで溢れてるなりよ
384デフォルトの名無しさん:2007/10/21(日) 18:32:15
2chは口が悪いのがデフォみたいなもんだからなあ。
385374=379:2007/10/21(日) 18:36:23
切れてないよw

http://hiro.asks.jp/20193.html
ひろゆき大先生のパターン2に従っただけさ

386デフォルトの名無しさん:2007/10/21(日) 18:39:14
口調の問題じゃなくて、有無を言わせない一方的な書き方で、
特定の選択肢を押し付けようと必死になってるように見える
まあつまらんことだが
387デフォルトの名無しさん:2007/10/21(日) 18:40:39
「コピーを戻している」と説明があるが?
388デフォルトの名無しさん:2007/10/21(日) 18:44:36
>>386
>>378でも>>379でもないが、俺もvector<>のコピーを戻すという設計は
正直コスト的に気になる。
>>379は(口は悪いが)それを親切に指摘しているだけに見えるよ。

まあ俺ならまっさきに考えるのは、古き良き引数での参照渡しだけれども。
389374=379:2007/10/21(日) 18:49:20
>>386

>>373さんが、どのような業務でこのコードをご利用になるのか、わたくしには推測できかねますので、的外れなご提案になっておりましたら
平にお詫び申し上げますが、>>378のコードでは、return result; を行う再に、ベクターの全要素がベクターのコピーコンストラクタによって
コピーされる処理が発生するおそれがあります。もちろん、コンパイラの戻り値最適化によってコピーがおこらないケースもありますが、必ず
そのことが保証されているわけではございません。もし、intのベクターに格納されている要素数が多い場合ですとか、ベクターに格納するのが
intではなく大きな構造体である場合、このことは性能上の大きな問題になることがございます。そこで、vector<int>* foo(); のように、foo()
の中でベクターをnewし、そのポインタを呼び側に戻すようにする設計を採用されますと、要素数が多い場合、一要素のサイズが大きい場合で
も、コピーの時間的コストの問題を回避することが可能でございます。また、現代ですと生のポインタでは無く、スマートポインタというもの
を用いることも可能でございます。その場合の関数シグネチャは、boost::shared_ptr<std::vector<int> > foo(); のようになるはずでござい
ます。残念ながら、ブーストやスマートポインタについてここで詳細にご説明差し上げることは困難ですので、御自分でググレカス

とでも書けと? 毎回こんなん書くほどひまじゃねーよw

#あ、RVOに触れたから>>379より親切になっちゃったw

390デフォルトの名無しさん:2007/10/21(日) 18:50:27
あらら切れちゃったw
391デフォルトの名無しさん:2007/10/21(日) 18:51:44
>>381>>390はcppllにでも帰ればいいんじゃね
392386:2007/10/21(日) 18:57:43
>>388
確かにコピーはコストが高いけど、無条件で避けるのが良いとは思わないな
頻繁に呼ばれない、かつ、返されるvectorがあまり大きくないことが分かっている関数なら、
コードの簡潔さのために値で返すのがよいと思う
モジュールの内部でのみ使う便利関数なら、とりあえず値で返しておいて、
コストが問題になるようなら別の方法に切り替えることもできるし

>>389
丁寧に書けなんて一言も言ってない
俺なら選択肢を提示するにとどめるので、「…できないか、よく考えとけ」という姿勢が
ちょっと気になっただけだ

あと、俺は>>381じゃないので、念のため
393デフォルトの名無しさん:2007/10/21(日) 19:04:16
もしくは参照渡しで格納場所を関数に渡してしまうという手もあるけれど…
394デフォルトの名無しさん:2007/10/21(日) 19:06:24
事実として、
・ >>379 は、元質問者が気づいていないかもしれない「コピーのコストの存在」と「避けかた」を示している。これはまさに>>392でいう選択肢の提示だ。
・ 一方、>>386は、選択肢の批判をするだけで、新しい情報の提供や、新しい選択肢は提示していない。これは典型的な煽り。
さて、どっちが有益?

>>392でようやく新しい情報の提示をしたのは評価するが。
395デフォルトの名無しさん:2007/10/21(日) 19:08:37
よくあるstringみたいに、コピーのコストがポインタ1-2個分しかないvectorって作れないんだっけ?
396デフォルトの名無しさん:2007/10/21(日) 19:13:37
>>395 std::auto_ptr<std::vector<T> >
397デフォルトの名無しさん:2007/10/21(日) 19:15:00
それは379他でガイシュツなので、vector単体でそういう実装ができるかどうかをキボン
398デフォルトの名無しさん:2007/10/21(日) 19:26:23
>>397
素直にコピーする vector の実装を vector_impl として、 shared_ptr<vecotr_impl> を
ラップする実装をコピーの軽い vector とすれば可能。
399デフォルトの名無しさん:2007/10/21(日) 19:28:31
そういう実装を採用しているSTLってありますか?>>398
400≠398:2007/10/21(日) 19:38:02
>>399

自分の記憶にはないなぁ
401デフォルトの名無しさん:2007/10/21(日) 19:39:32
>>400
コピーのコストを優先すると何を捨てることになるんだろう。ちょっと考えてみる。トンクス。
402デフォルトの名無しさん:2007/10/21(日) 19:43:32
全てを参照でもちまわるという発想は実はGC型の(つまり、多くの)
オブジェクト指向言語と同じだ
GCの代わりをshared_ptrでやろうってこったな
循環参照には無力だが

コピーを安価にするためにはコピーオンライトというテクニックが伝統的に
使われているが、マルチスレッド環境では正直微妙で、下手に使うと
弊害のが多いかもしれん。
403デフォルトの名無しさん:2007/10/21(日) 19:44:38
>>379です
皆さんいじってくれておおきにww
全然切れてナイッスヨww
STLの参照渡しは最近のお気に入りで乱用しているんだけど
(便利がいいですよね、巨大コンテナも楽々動作してる感じ)
実は、相関関数のクラスライブラリィがどうしても必要になって、
一月程前、STLを覚え始めた頃に作ったコマンドラインで動作する
相関関数のプログラムのコードをいじくりまわしていたら、当事は参照渡しが
使えなかったので、ベクトルをprivateで宣言して、クラス内で可視できるように、
まぁまぁ巧く実装してあったんだけど(自画自賛ww)
ふと、参照渡しができるのなら、参照返しも出来る悪寒がしたので、
あまり期待してなかったんだけど、ここで尋ねてみたってかんじです。
404デフォルトの名無しさん:2007/10/21(日) 19:46:13
>>402
std::stringはCoWが多いようだね。
405デフォルトの名無しさん:2007/10/21(日) 19:50:43
>>392のまとめ:

コピーのコストが安いことがあるのを忘れるなよ。コードの簡潔さのために
vector<int> foo();
とできないか、よく考えとけ。

感想: 392の「よいと思う」と379の「よく考えとけ」の違いがわからん。俺なら選択肢を提示するにとどめ、「よいと思う」などとは書かない。それと値で戻すコードが簡潔だと考えるのは392の主観で、押し付けがましい。


>>403
よし、次はこれだな。と釣ってみる。
vector<int>& foo()
{
  vector<int> result;
    return result;
}
406デフォルトの名無しさん:2007/10/21(日) 19:57:19
>>402 >>404
まえつかってたSTLのstringは、x86むけにしかスレッドの排他制御のコードがはいってなくて、AMD64でそれを使って盛大にあぼーんした。
402のいうマルチスレッドだと微妙、というのは排他制御のコストの話かもしれないけど。
407デフォルトの名無しさん:2007/10/21(日) 19:58:13
>>379です
イテレータで返す方法とかもありだな
408379:2007/10/21(日) 20:01:20
>>403 >>407
誰?w
409デフォルトの名無しさん:2007/10/21(日) 20:04:55
スマソ>>378でした
ってゆうかイテレータで返す方がつぶしが利きそうだな

410デフォルトの名無しさん:2007/10/21(日) 20:06:05
>>405
ローカル変数の参照、ポインタは返しちゃいかんでしょ。
関数抜けたら変数なくなってる。
411デフォルトの名無しさん:2007/10/21(日) 20:11:56
>>409
書いてみて。
>>410
釣ら..
412デフォルトの名無しさん:2007/10/21(日) 20:25:48
>>409ですが、まだ初めて一ヶ月くらいなんで間違ってるかもしれんが
vector<string>を引数で渡す場合でこんな感じかな
template<typename Iter>
void sub(Iter first, Iter last) {
string foo;
while ( first != last ) {
foo = *first++;
...
}
}


vector<string> vs;
list<string> ls;
string as[5];

sub(vs.begin(), vs.end());
sub(ls.begin(), ls.end());
sub(as, as+5);
413デフォルトの名無しさん:2007/10/21(日) 20:36:16
>401
copy-on-write するなら実体を共有してるうちのどれかに書き込みが発生したときに vector 全体のコピーをしなければならない。
ということで、要素に対する参照や末尾に対する追加が constant time にならず標準の要求を満たさないと思う。

>404
最近は >402 の如く排他制御のコストが高いってんで CoW は避ける方向だと思う。
414デフォルトの名無しさん:2007/10/21(日) 20:38:26
>>412
それは「イテレータで返す」とはいわないだろう。。。。。。
「イテレータを渡す」というような。

日本語nativeじゃないとかだったらゴメンだけど。
415デフォルトの名無しさん:2007/10/21(日) 20:42:46
>>413
ありがとう。
ということは、最近は std::string foo(); もそれなりにコストかかるんだね。
416デフォルトの名無しさん:2007/10/21(日) 20:42:53
vector<int>をリターンする代わりにiteratorを使うんなら
引数は出力イテレータ一個でいいな。で、
vector<int> vec;
foo(back_inserter(vec));
とかやる。
417デフォルトの名無しさん:2007/10/21(日) 21:04:43
>411 自体も「違うこと考えてんじゃねーの?」と思って突っ込んだんだろうけどね。
ただ、処理の内容にもよるけど iterator で返すことは不可能じゃなくて、
iterator で受けて iterator で返す→いっそ range で受けて range で返せば!→
oven キタ|std::string("タキ")|reversed|cycled(5)|━(゚∀゚)!!!!!
って感じだと思う。
ttp://p-stade.sourceforge.net/oven/doc/html/index.html
418デフォルトの名無しさん:2007/10/21(日) 21:11:13
そろそろ右辺値参照という今すぐ使えないものをねだってみる。
419デフォルトの名無しさん:2007/10/21(日) 21:13:20
>>417
彼は特殊だから。。。もちろんいい意味で。
420デフォルトの名無しさん:2007/10/21(日) 21:41:02
>>413
その理屈でいくと、 string を copy-on-write で実装するのも不味くないか?
string には計算量の制約が無いんだっけ?
421デフォルトの名無しさん:2007/10/21(日) 22:33:49
libstdc++の.tcccファイルって何?
なんで.hと分離してんの?
422デフォルトの名無しさん:2007/10/21(日) 22:58:19
>>413
今Fedora(Linux)のlibstdc++-4.1.2を見てみたが、refcountされてる。
423デフォルトの名無しさん:2007/10/21(日) 23:04:36
>>417
怪しいoven君キタ━━━━━━(゚∀゚)━━━━━━ !!!!!
424デフォルトの名無しさん:2007/10/21(日) 23:06:04
そんなにrangeっていいのだろうか

必要性を見出せないのは俺があんまり複雑な事をやってないからかな
425デフォルトの名無しさん:2007/10/21(日) 23:22:10
いまぱっとしらべた感じだと、
- VC7以降と最近のSTLPortは単純コピー、スレッドセーフ
- g++3/4(libstdc++)は参照カウント、スレッドセーフティーは怪しい、たぶんアンセーフ
- BCCも参照カウント、スレッドセーフティは不明
みたいだな。More Exceptional C++になんか書いてあるらしいが持ってない。amazon.comに注文かけた。

426デフォルトの名無しさん:2007/10/21(日) 23:27:54
rangeでpush_backしてもらうように書けたっけ?
まぁpair<iteratoriterator>がコンテナ風味に使えるのは便利だはな
427デフォルトの名無しさん:2007/10/21(日) 23:32:03
>>425
>たぶんアンセーフ
ソース見たら、_Atomic_Word 使ってなんか操作してるな。大丈夫かも。よくわかんね。
428デフォルトの名無しさん:2007/10/22(月) 00:10:33
>>424
BOOST_FOREACHなんてどうよ?
あとはrange_ex使えば、アルゴリズム関数の引数で、
c.begin(), c.end()としていたところを
単にcとすればよくなることとか。
429デフォルトの名無しさん:2007/10/22(月) 00:44:01
430デフォルトの名無しさん:2007/10/22(月) 04:31:36
>>424
rangeがあれば

auto rng = transformed(sorted(filtered(
  equal_range(c, "foo"), identity()), converter<T>());
vector<T> v(rng); // ここで初めて計算

みたいなことが余分な作業領域とコピー無しでできるよ
431デフォルトの名無しさん:2007/10/22(月) 08:43:18
また怪しげなpsendo
432デフォルトの名無しさん:2007/10/22(月) 08:48:41
最近boost触り始めたんだけど、boostの事をぐぐるとちらほら見かける"oven"ってなに?
433デフォルトの名無しさん:2007/10/22(月) 08:57:51
オーブンレンジ
434デフォルトの名無しさん:2007/10/22(月) 11:05:56
435デフォルトの名無しさん:2007/10/22(月) 12:29:13
一行野郎と相性がよさそうだな
436デフォルトの名無しさん:2007/10/22(月) 12:31:07
>oven
rangeに対応したアルゴリズムライブラリでなかったか?

range≒レンガからか…無茶か…
437デフォルトの名無しさん:2007/10/22(月) 12:38:32
煉瓦?
438デフォルトの名無しさん:2007/10/22(月) 13:00:11
オーブンレンジだろ、常考
439デフォルトの名無しさん:2007/10/22(月) 13:10:41
eggとかもあるね、そういえば
440デフォルトの名無しさん:2007/10/22(月) 13:26:52
boost vaultとか覗くと俺の欲しいものの9割ぐらいが既により高い完成度で提供されてて笑える
これフルに利用したらC++でもLL言語とか使うより手早くソフト作れるんじゃね?
441デフォルトの名無しさん:2007/10/22(月) 13:37:23
お前がやればな
442デフォルトの名無しさん:2007/10/23(火) 18:44:23
>>440
そういう現実をみせつけられると生きている意義が見いだせないよな。
まぁ、俺もゼミで毎週言われていることだが。
443デフォルトの名無しさん:2007/10/23(火) 19:06:40
monthという配列の要素は月を表します、月変りが発生した要素の番号を取得するのにSTL的にははどうしたらいいですか
例えば
int month = [10, 10, 11, 11, 11, 12, 12, 1];
の場合
3,6,8が求めたい
444デフォルトの名無しさん:2007/10/23(火) 19:08:22
それはSTLと関係あるのだろうか?
445デフォルトの名無しさん:2007/10/23(火) 19:15:36
そういうアルゴリズムが用意されていますか?
ってことじゃね?

俺なら普通にイテレータで舐めるなぁ。
446デフォルトの名無しさん:2007/10/23(火) 19:23:07
うー、なんで2,5,7じゃないんだろ。
447デフォルトの名無しさん:2007/10/23(火) 19:27:50
>>443です
>>444
>>445
そうです、アルゴリズムのmismatchが使えるかなと思いましたが無理でした
>>446
普通に2,5,7でもいいです
448デフォルトの名無しさん:2007/10/23(火) 20:20:58
mismatchが使いたいなら使える。

# include <algorithm>
# include <iostream>

int main()
{
  int v[] = {10, 10, 11, 11, 11, 12, 12, 1};
  int *first = v, *last = v + (sizeof v / sizeof v[0]);
  while(first != last)
  {
    first = std::mismatch(first + 1, last, first).first;
    if(first != last)
      std::cout << first - v << "\n";
  }
}
449デフォルトの名無しさん:2007/10/23(火) 21:13:47
>>448サンクス
mismatchは二つのシーケンスが必要だと思っていたんですが、一つでも出来るんですね。
ところで後だしで申し訳ないですが、要素が年月日の場合同じく、月変りが発生した要素の番号を取得する場合は、どうしたらいいのか教えてもらえませんか
substrで月を切出していくと思うのですがどの様に使ったらいいのかわかんないんで・・・・・
int v[] = {20071001, 20071002, 20071103, 20071120, 20071122, 20071201, 20071208, 20080105};
450デフォルトの名無しさん:2007/10/23(火) 22:56:57
>>449
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
pair<InputIterator1, InputIterator2>
mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, BinaryPredicate pred);
451デフォルトの名無しさん:2007/10/24(水) 03:46:07
ここは adjacent_find() の出番だろ。
452デフォルトの名無しさん:2007/10/24(水) 03:48:39
>>449
int に substr() じゃ、どの様に使ったらいいかわからんわな。
v の要素が string のつもりなら substr() して atoi() しとけばいいでしょ。
453デフォルトの名無しさん:2007/10/24(水) 13:04:25
既出だったらスマヌ。
コンパイルは通るけど、例外で死ぬ〜…(VC7)

list<foo *> fooList;// <- 多態性を持たせるためポインタです

/* なんかいろいろ */

for(list<foo *>::iterator fooIt = fooList.begin(); fooIt != fooList.end(); ++fooIt)
{
(*(fooList.begin()))->hoge(); //意味はないけどOK

(*fooIt)->hoge(); //NG...orz (ポインタが取れていないらしい...)
}
454デフォルトの名無しさん:2007/10/24(水) 13:32:01
((foo *)*fooIt)->hoge();
455デフォルトの名無しさん:2007/10/24(水) 13:47:11
>>453
おかしいようには見えない。
何か別のところで変なことしてるんじゃないか?
例えばこれなら正しく実行できると思う。
# include <list>
# include <iostream>

using namespace std;
struct foo { virtual void hoge() = 0; ~foo(){} };
struct bar : foo { void hoge() { cout << "bar::hoge\n"; }};
struct baz : foo { void hoge() { cout << "baz::hoge\n"; }};

int main()
{
  list<foo *> fooList;

  fooList.push_back(new bar);
  fooList.push_back(new baz);
  fooList.push_back(new bar);

  for(list<foo *>::iterator fooIt = fooList.begin(); fooIt != fooList.end(); ++fooIt)
    (*fooIt)->hoge();
}

>>454
そのキャストは無意味だろ。
456453:2007/10/24(水) 14:20:29
解決しました〜お騒がせしやした。

fooList = getFooList();
な部分があったので、

 list<foo *> getFooList();
 ↓
 list<foo *>& getFooList();

で普通に通るようになりましたとさ。

…理由は究明中ってことで。
457デフォルトの名無しさん:2007/10/24(水) 17:15:04
(**fooIt).hoge();
458453:2007/10/24(水) 22:03:44
誤りがあったので訂正…
このように省略していたのをちゃんと書けば普通に動きました。
>>456
のような対処は必要ないです。
…違う意味になるってことか?

[誤]
for(list<foo *>::iterator fooIt = (getFooList()).begin(); fooIt != (getFooList()).end(); ++fooIt)
{
 (*fooIt)->hoge(); //NG...orz
}
 ↓↓↓
[正]
list<foo *> fooIt getFooList();

for(list<foo *>::iterator fooIt = fooList.begin(); fooIt != fooList.end(); ++fooIt)
{
 (*fooIt)->hoge(); //OK
}
459デフォルトの名無しさん:2007/10/24(水) 22:18:59
>>458
fooIt = getFooList().begin()と書くと、getFooListが呼ばれ、その結果が一時オブジェクトにコピーされ、
その一時オブジェクトに対してbeginが呼ばれ、その結果がfooItに格納され、一時オブジェクトが破棄される。
この時点でfooItの指す先は既に破壊されているので、fooItは無効なイテレータ。
さらにfooIt != getFooList().end()とすると、また別の一時オブジェクトが作られて、
そのendとfooItが比較されるわけで、当然まともに動かない。
460デフォルトの名無しさん:2007/10/24(水) 22:58:32
>420
> 14882:2003 23.1.2 / 12
>Table 68 lists sequence operations that are provided for some types of sequential containers but not
> others. An implementation shall provide these operations for all container types shown in the ‘‘container’’
> column, and shall implement them so as to take amortized constant time.
で、Table 68 に operator[] があるけど、string は書かれていないのでこの制約にかからない。
insert() とか Table 67 にあるものは、コンテナ依存なんだけど、vector については 23.2.4 / 1 他に記述がある。

後、iterator の無効化についても規格の記述を満たさなくなると思うけど、こっちは string 自体にも指摘がある。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#263

将来的には string は seqence container ではない、という扱いになるっぽい。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#718
461453:2007/10/25(木) 08:57:44
>>459
理屈もわかってすっきりです。
ありがとうございました。
462デフォルトの名無しさん:2007/10/26(金) 08:00:35
質問です。multimapを使って「ある部屋に入ってきた人数(double)」と「最初の人が入ってから現在までの経過した時間(int)」と
「その人達が動き出す未来の時間(int)」を記録してmultimapに格納したいと思っています。それで普通は

#include <map>
typedef std::multimap< int, double, std::less< int > > Mmid;
    :
Mmid pairs;
cout << "\nNode Multimap pairs contains:\nKey\tValue\n";
for( Mmid::const_iterator iter = pairs.begin(); iter != pairs.end(); ++iter )
cout << iter->first << '\t' << iter->second << '\n';
とやるところを
typedef std::multimap< int, int, double, std::less< int > > MmidX; //宣言はビルド通ります
MmidX trios; //←ここで定義するとエラーが出ます
とやったら
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_multimap.h: In instantiation of ‘std::multimap<int, int, double, std::less<int> >’:
edge.h:49: instantiated from here
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_multimap.h:118: error: no type named ‘value_type’ in ‘struct std::less<int>’
     :
/usr/lib/gcc/i486-linux-gnu/4.1.2/../../../../include/c++/4.1.2/bits/stl_multimap.h:170: error: using invalid field ‘std::multimap<_Key, _Tp, _Compare, _Alloc>::_M_t’
make: *** [edge.o] エラー 1
とエラーが出ます。
multimapってやっぱりキーともう一つ対になる値の二つしか保持できないんですか?
もし、そうだとしたら他に何か良い案はありませんか?
463デフォルトの名無しさん:2007/10/26(金) 09:01:51
こうか?
std::multimap<int, std::pair<int, double>, std::less<int> >
何をしたいのかよくわからんが。
464デフォルトの名無しさん:2007/10/26(金) 10:10:34
ある部屋をキーにして、複数の値を格納したい。
ある部屋をキーにすると、Mapでは1つしか格納できないからMultiMap<これが間違い
MultiMapなら引数をたくさん取れる<これも間違い

素直にstructとmapで実装したほうが早いかと。
てか、multimapの仕様書ちゃんと見たら?
STL解説ページでもいいけど。

struct room
{
double a;
int b;
int c;
}

typedef multimap< int, room > d;
465デフォルトの名無しさん:2007/10/26(金) 20:40:22
そこで boost::tuple ですよ。
466デフォルトの名無しさん:2007/10/27(土) 00:15:34
なんか Boost スレがおかしなことになってるね
467デフォルトの名無しさん:2007/10/27(土) 03:06:51
まず、人数がdobuleなのが不可解。
深遠な理由があるのかも知れないが。
468デフォルトの名無しさん:2007/10/27(土) 03:07:39
すまん、doubleね。
469デフォルトの名無しさん:2007/10/27(土) 06:18:59
long や longlong 以上の桁の数字が入るが
下の方の桁の正確さは求められていないっつーことか
じゃ最初から 1/1000 とか 1/10000 とかで int にした方がいいね
470デフォルトの名無しさん:2007/10/27(土) 16:32:36
long long以上の人数って…
471デフォルトの名無しさん:2007/10/27(土) 16:52:54
アカシックレコードでも作ってるのかもしれん
472デフォルトの名無しさん:2007/10/27(土) 17:37:15
過去に死んだひとと同じIDをあとから生まれたひとに振ると問題あるだろ
2000年問題の騒ぎどころじゃなくなる
473デフォルトの名無しさん:2007/10/27(土) 17:49:57
誤差ありで厳密に比較できないIDって何だそら
474デフォルトの名無しさん:2007/10/27(土) 18:17:52
doubleはただのホルダで
long longが使えない環境のために64bit整数を保持しているのかも知れん。
475デフォルトの名無しさん:2007/10/27(土) 20:31:29
int_64t とかじゃだめなん?
476462:2007/10/28(日) 07:26:22
大変長らくお待たせしました。

>>464さんの方法を読んで一時間くらいでなんとか出来ました。
これは便利ですね。いくらでも送りたい放題じゃないですか。
実はキーは「その人達が動き出す未来の時間(int)」でしたので
構造体の中の要素は二つで済みました。

>>467->>475
そこまで深遠な理由はありませんよ。w
人数がdoubleなのは確率に基づいて計算するからなのです。
ですから、「部屋@から部屋Bへ9.844人が移動」とかあり得ます。

見た目は簡単そうな式なのですが、プログラムにすると大変ですね。
それでSTLのお世話になったのですが、
皆さんのお陰でSTLの問題は解決しましたので
後は送った値をどう処理するかですね。
うまくいくといいんですが…。

これからも度々お世話になると思います。
皆さん、どうもありがとうございました。
477デフォルトの名無しさん:2007/10/28(日) 07:56:48
そんなことしたらキーが一致しないかも知れない心配をしないといけないぞ
478デフォルトの名無しさん:2007/10/28(日) 09:00:42
現在の高校3年以下の人間は中学でイオンや三角関数を学ぶ時代まで遡るべき。
479デフォルトの名無しさん:2007/10/28(日) 15:18:50
あれ?今は習わないの?
三角関数のテイラー展開くらいまでは高校で習ったが・・・

しかし厳密な収束性とか大学に入るまで
一切気にしてなかったのは秘密だ。
480デフォルトの名無しさん:2007/10/28(日) 16:53:58
>>479
旧過程と新過程の試験問題比べれば分かる、センターと一次試験?
481462:2007/10/28(日) 21:09:40
>>477
キーは「その人達が動き出す未来の時間(int)」ですので大丈夫じゃないですか?
そういう意味ではなくてですか?
482デフォルトの名無しさん:2007/10/29(月) 03:48:06
setつかうよりmapのほうが良いんですか?
setのみで済むときでも順番にキー付けておけば配列のように使えますから
setのほうが速いとかすぐれている点はありますか?
483デフォルトの名無しさん:2007/10/29(月) 03:55:54
>順番にキー付けておけば配列のように

よくわからん
どういう使い方?
484482:2007/10/29(月) 04:03:42
#include <map>
#include <string>
#include <iostream>
using namespace std;

typedef map<int, string> Set;

main(){
Set x;
x.insert( Set::value_type( 3, "日本" ) );
x.insert( Set::value_type( 1, "日本語化" ) );
x.insert( Set::value_type( 2, "入門" ) );
x.insert( Set::value_type( 0, "ニュース関連" ) );

x[1] = "ニュークリアス";

cout << x[0] << endl;
cout << x[1] << endl;
cout << x[2] << endl;
cout << x[3] << endl;
}
485482:2007/10/29(月) 04:05:49
でも、キーでソートしてしまうから、右側の"日本"だけのソートとは別ですね
486デフォルトの名無しさん:2007/10/29(月) 04:28:11
検索した物が何番目か調べるのはこういう風にやれば良いんですか?

#include <set>
#include <string>
#include <iostream>
using namespace std;

main(){
set<string> x;
x.insert("入門" );
x.insert("ニュークリアス" );
x.insert("ニュース関連" );

set<string>::iterator p = x.begin();
while( p != x.end() ){
cout << *p << endl;
p++;}

p=x.find("入門");
cout<<endl<<&p-&x.begin();
}
487デフォルトの名無しさん:2007/10/29(月) 04:35:39
これ固まるんですけどわかりますか?

#include <set>
#include <string>
#include <iostream>
using namespace std;

main(){
set<string> x;
x.insert("入門" );
x.insert("ニュークリアス" );
x.insert("ニュース関連" );

set<string>::iterator p,q=x.begin();
p=x.find("入門");
cout << (int)distance( p, q );
}
488デフォルトの名無しさん:2007/10/29(月) 04:47:53
おなじですけどこれ動かない理由わかりますか?

#include <set>
#include <string>
#include <iostream>
using namespace std;

main(){
set<string> x;
x.insert("1" );
x.insert("2" );
x.insert("3" );
cout << (int)distance(x.end(),x.begin());
}
489デフォルトの名無しさん:2007/10/29(月) 04:49:10
わかりました 値がマイナスになると固まるようです
cout << (int)distance(x.begin(),x.end());
490デフォルトの名無しさん:2007/10/29(月) 07:13:11
>>486
いいえ。

>>487
q が未初期化だから何がおきても不思議じゃない。

>>488
distance() の第1引数は第2引数へ到達可能でなければならないが、
end() は begin() へ到達可能ではないから。

>>489
値がマイナスになっていたわけじゃない。
491デフォルトの名無しさん:2007/10/29(月) 08:36:56
>>490
487 の q は初期化されてるだろ。
492デフォルトの名無しさん:2007/10/29(月) 08:54:42
http://msdn2.microsoft.com/en-us/library/kt2s1e2h(VS.71).aspx
この有様だから間違えるのも仕方ない
493デフォルトの名無しさん:2007/10/29(月) 08:55:24
>cout << (int)distance( p, q );
pとqの位置をひっくり返せばいいんじゃないかな。

#include <set>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;

int main()
{
set<string> x;

x.insert("C++" );
x.insert("STL" );
x.insert("BOOST" );

set<string>::iterator p, q = x.begin();
p=x.find("STL");

cout << (int)distance( q, p ) << endl;

return 0;
}


これで動いたよ。俺の環境では2バイト文字使うの面倒だからちょっと変更したけど。
494デフォルトの名無しさん:2007/10/29(月) 08:58:51
> This function returns the distance between two iterators by determining how many times
> the first iterator would need to be incremented until it was equal to the last iterator.

忘れてならないのは、この"incremented"ってとこですかね。
495デフォルトの名無しさん:2007/10/29(月) 10:04:11
STLの各アルゴリズムはSSEを使うようには最適化されていないのでしょうか?
496デフォルトの名無しさん:2007/10/29(月) 10:07:18
>>495
コンパイラとライブラリ実装による。
ヘッダファイルに定義があるだろうから読んでみればわかるかもしれない。
497デフォルトの名無しさん:2007/10/29(月) 10:54:15
mapってアイテムinsertしていくとどっかでvectorみたいに領域確保しなおしでアドレス変わったりしますか?
mapの中身を指してるポインタを外部に持ってるんですけど、こういうのって良くないんでしたっけか。
498デフォルトの名無しさん:2007/10/29(月) 12:36:36
>>495
SSEを使うかどうかはアルゴリズムの問題じゃなくてコンパイラとコンパイルオプションの問題だろ。
499デフォルトの名無しさん:2007/10/29(月) 12:46:22
>>497
その操作でイテレータが変わらないのは仕様にあったと思う。
ポインタにまで言及しているかは知らない。
500デフォルトの名無しさん:2007/10/29(月) 12:49:30
valarrayなんかはSSEで最適化してくれないと存在意味ないと思う
501デフォルトの名無しさん:2007/10/29(月) 13:05:21
>>500
そういう人は使わなくていいんじゃね?
502デフォルトの名無しさん:2007/10/29(月) 23:04:40
>>497
map, set, multimap, multiset のイテレータおよび参照はコンテナから削除されるまで有効。

23.1.2p8
> The insert members shall not affect the validity of iterators and references to the container, and the erase
> members shall invalidate only iterators and references to the erased elements.
503497:2007/10/30(火) 12:23:11
>>499, 502
サンクスです!
504デフォルトの名無しさん:2007/10/31(水) 18:46:51
accumulateの第三引数ってなに?
505デフォルトの名無しさん:2007/10/31(水) 18:55:36
初期値
506デフォルトの名無しさん:2007/11/01(木) 12:26:38
vector で、iterの示す位置indexを得る簡単な方法はあるでしょうか?
507デフォルトの名無しさん:2007/11/01(木) 12:30:43
>>506
そのイテレータの対象となるヴェクタのビギンとの差でいいじゃん。
508デフォルトの名無しさん:2007/11/01(木) 12:46:11
>>506
std::distance( vector.begin(), iterator );
509506:2007/11/01(木) 12:56:21
>>507-508
早速どうもです。
なるほろ、vectorはメモリ順序保証なんですね。
これでやってみます。有難う御座いました。
510デフォルトの名無しさん:2007/11/01(木) 13:18:49
>>509
メモリ順序とか関係ない。
511デフォルトの名無しさん:2007/11/01(木) 13:28:02
x ビギン
o ヴィギン
512デフォルトの名無しさん:2007/11/01(木) 13:33:24
>>511
beginのどこをどう読んだらヴィギンに?
513デフォルトの名無しさん:2007/11/01(木) 13:38:43
沖縄の風を感じたので
514デフォルトの名無しさん:2007/11/01(木) 13:53:54
energyをわざわざ「エナズィー」をカッコつけて歌ってる歌があったなぁ。
515デフォルトの名無しさん:2007/11/01(木) 14:10:49
有料ゴミのレディオ
516デフォルトの名無しさん:2007/11/01(木) 16:03:25
スィークゥワーサァー
517デフォルトの名無しさん:2007/11/01(木) 17:42:22
正規表現でよさそうなのみつけた

http://www.geocities.jp/kosako3/oniguruma/index_ja.html
518517:2007/11/01(木) 17:52:28
windwosXPでサブディレクリまで文字を正規置換するいいソフトないのでつくろうとおもうけど
boostと>>517どっちがいい?
519デフォルトの名無しさん:2007/11/01(木) 18:17:21
使いやすいほう
520デフォルトの名無しさん:2007/11/01(木) 18:18:23
>>517
boostスレに行け
521デフォルトの名無しさん:2007/11/01(木) 18:27:55
文字を正規置換って、ファイルやフォルダのリネームのことか?
Flexible Renamerで十分事足りてるんだが。
522デフォルトの名無しさん:2007/11/01(木) 18:35:47
ファイル中身
523デフォルトの名無しさん:2007/11/01(木) 21:18:29
UTF8のファイルなんですが・・同じ文字を削除して出力したいのですが・・
stringでは読み込めません いい方法ありますか?

http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/5193.txt
524523:2007/11/01(木) 21:21:26
これだとだめです

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

main(){
string a,b;
fstream fp("dd",ios::in);
for(;;){
getline(fp, b);if(fp.eof())break;
a=b.substr(0,2);
b=b.substr(4,2);
if(a!=b)cout<<a<<"\t"<<b<<"\n";
}}
525デフォルトの名無しさん:2007/11/01(木) 21:26:56
526523:2007/11/01(木) 21:29:19
>>525
どうやったらいいですか?
527523:2007/11/01(木) 21:35:05
できました
528デフォルトの名無しさん:2007/11/01(木) 21:39:39
>>527
どうやって?
529デフォルトの名無しさん:2007/11/01(木) 22:02:41
普通にUTF8をパースすればいいんじゃね
ていうかスレ違いじゃね
530デフォルトの名無しさん:2007/11/01(木) 22:23:10
stringで全角1文字が2バイトではないみたいなんですけど1文字取得したいときはどうすればいいですか
531デフォルトの名無しさん:2007/11/01(木) 22:32:16
そういうのはwchar_tに変換してからゆっくり調理してやれば、
532デフォルトの名無しさん:2007/11/01(木) 22:36:38
>>531
サンクス
533462:2007/11/03(土) 09:10:13
また、お世話になります。>>462です。
<multimap>のerase()の括弧の中に何を入れれば、一番最初かもしくは一番最後の要素が消せるのでしょうか?
数字を入れるとキーが消せるのは分かるのですが、IteratorのPositionで消す方法が分かりません。
エスパー能力が必要かもしれませんが、どうかプログラムの断片を診てやってください:
■ edge.h ■
#include <map>
typedef std::multimap< int, double, std::less< int > > Mmid;

struct TIMESTRUCT
{
int arrivalTime;// arrival time = day time
double avatar; // number of avatars in a bank
};

TIMESTRUCT timeCapsule;
Mmtc atTime; // declare the multimap atTime;
■ node.cpp ■
if (edge->sourceNode() == this) {
edge->timeCapsule.arrivalTime = dTime;
edge->timeCapsule.avatar = edge->_bank2;
edge->atTime.insert( Mmtc::value_type( dTime + edge->r(), edge->timeCapsule ) ); //挿入しています
}
Mmtc::const_reverse_iterator r_iter;
for( r_iter = edge->atTime.rbegin(); r_iter != edge->atTime.rend(); ++r_iter ) {
edge->xWander = dayTime - ( (r_iter->second.arrivalTime - 1) + edge->r() );
cout << r_iter->first << '\t' << r_iter->second.arrivalTime << "\t\t"
<< r_iter->second.avatar << "\t\t" << edge->xWander << "\n";
}

edge->atTime.erase(5); // 問題はこの括弧の中です;これだとキーが'5'の要素だけが消せます
edge->atTime.erase(r_iter.rend()); // コンパイルできません;mo matching
よろしくお願いします。
534デフォルトの名無しさん:2007/11/03(土) 09:20:41
>>533
const_reverse_iteratorにrend()なんてメソッドがあるかよく調べるんだ
535デフォルトの名無しさん:2007/11/03(土) 09:26:34
つーか、期待されるべきrend()は要素を指さないだろ。
536デフォルトの名無しさん:2007/11/03(土) 09:27:05
つうかend()は無効なイテレータなんで渡しちゃだめ
537462:2007/11/03(土) 09:29:48
え、でも…

ttp://www14.atwiki.jp/yonecle/pages/13.html

rend()
reverse_iterator rend();
const_reverse_iterator rend() const;
…コンテナの先頭を指す逆方向反復子を返す。

本当にこれだけじゃなくていろいろやってみたんですよ。
もうアイディアが尽きました。

●erase()
void erase( iterator i); ←これと
…iが指す要素を削除する。

void erase( iterator start ,iteraterend); ←これの意味が分かりません
…startからendまでの範囲の要素を削除する。

size_type erase( const key_type& k);
…コンテナからキーの値がkである要素を削除する。

・・・取り敢えず、r_iterは使いますよね?
538462:2007/11/03(土) 09:33:42
>>535-536
はっ!
そうでした!
でも'rbegin()'でもダメだったような気が・・・

それにしてもこれに関する例って
ただのひっっっっっとつもないんですよ・・・。
これだけ探してないとなるとびっくりしますよ。
あったら御一報願います。
539デフォルトの名無しさん:2007/11/03(土) 09:35:35
rend()はイテレータが持ってるんじゃなくて、コンテナが持ってる
edge->atTime.rend()
540462:2007/11/03(土) 09:41:17
>>539
はい、自分もここ

for( r_iter = edge->atTime.rbegin(); r_iter != edge->atTime.rend(); ++r_iter ) {

で使っています。

あっ!
もしかしてr_iterだけで良かったのかも!

edge->atTime.erase(r_iter); // ←現在指している要素

正解ですか?

それなら
r_iter = edge->atTime.rbegin();
ってやっておいて
edge->atTime.erase(r_iter);
なら最初の要素が
r_iter = edge->atTime.rend();
ってやっておいて
edge->atTime.erase(r_iter);
なら最後の要素が消せますよね?
541462:2007/11/03(土) 09:42:45
いかん。
r_iter = edge->atTime.rend();
ってやっておいて
edge->atTime.erase(--r_iter); // ←落とし穴
なら最後の要素、ですね?
542デフォルトの名無しさん:2007/11/03(土) 09:49:47
begin() 最初の要素
rbegin() 最後の要素
543462:2007/11/03(土) 09:53:52
>>542
はっ!
そうだったんですか!
C++の本の付録のページで勉強してますからね・・・。

また一つ賢くなりました。
皆さん、またまたご協力ありがとうございました!
544デフォルトの名無しさん:2007/11/03(土) 10:01:24
>>543
ネット使えてるんならいくらでもSTL解説サイト見れるだろう
545デフォルトの名無しさん:2007/11/03(土) 10:09:27
rbegin().base()
546462:2007/11/03(土) 10:14:50
>>544
はい、もういろいろ読みました。
http://www.sgi.com/tech/stl/ ←こことか
でも、何故か「辞書」みたいなのしか見つからないんですよね:

●erase()
void erase( iterator i);
void erase( iterator start ,iteraterend);
size_type erase( const key_type& k);

・・・何故にそんなにボトムアップなんだろうって思います。
英語の辞書を読んで英会話をマスターしているような気分です。
時々、STLってC++本体とは別物に思えます。

あ、もうこんな時間じゃないですか!
・・・では、寝ますです(^_^)/~

>>545
え、その.base()というのは何ですkZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
547デフォルトの名無しさん:2007/11/03(土) 11:58:14
>546
>時々、STLってC++本体とは別物に思えます。
ライブラリなんだから、そのライブラリの「お約束」を知る必要があるのは当然。

>でも、何故か「辞書」みたいなのしか見つからないんですよね:
いくつかの基本的な概念さえ押さえておけば、後は「辞書」みたいものだけで事足りるから。
つまり(自覚してると思うけど)今足りないのは基本的な概念の把握。
これも割と辞書的ではあるけど
ttp://www005.upp.so-net.ne.jp/episteme/html/stlprog/
あたりを読んでみれば?
で、もうちょい概念を押さえたら EffectiveSTL を読んどくのがおすすめ。
例えば今回の件は、第 26 項、第 28 項を読めば解決するはずだ。

簡単に言えば、コンテナのメンバ関数には reverse_iteartor を渡せないので
base() を使って iterator に変換してやる必要がある。
ただしその際、(削除を行う場合には)位置の調整をしてやる必要があるため、
container.erase((++r_iter).base());
みたいにする必要がある。
なお、ループしてる際の erase には iterator の無効化という別の問題があるため
それにも注意が必要(EffectiveSTL 第 9 項参照)。
548デフォルトの名無しさん:2007/11/03(土) 13:02:00
すいません、初歩の初歩かもしれないですが
vectorやlistの要素へのポインタを持つ場合( p = vec[6]; とか p = &itLit )
このpがずっと安全にその要素をさしつづける保証はあるのでしょうか?

・当然元の vector や list が開放されればさせなくなるのはわかります
・たしか、vectorはpush_backしていくとメモリーの再確保が発生するので、要素の存在位置がかわるはず
・listは双方向リストだから大丈夫?
・mapのsecondとかは? firstはソートされるため変化しそう

google

549デフォルトの名無しさん:2007/11/03(土) 13:23:21
>>548
listとmap類は大丈夫。mapのfirstも。
ついでに言うと、mapはpair<key, value>を保持している訳だから、
firstが動いてsecondが動かないということはありえない。
ソートはポインタの付け替えでできる。
550デフォルトの名無しさん:2007/11/03(土) 13:30:00
>548
>vectorやlistの要素へのポインタを持つ場合( p = vec[6]; とか p = &itLit )
どっちも要素へのポインタと思えないのが少し不安。
551デフォルトの名無しさん:2007/11/03(土) 14:47:08
>>549
firstも大丈夫なんですか!?
どうやって二分探索してるんでしょうmapは・・・

ソートはポインタの付け替えでできる・・・?うーん、STLの本買うと面白そうですね


>>550
p=&vec[6]ですね。
p=itList
ですね。お恥ずかしい
552デフォルトの名無しさん:2007/11/03(土) 15:07:18
mapは
struct node {
  pair<const key_type, mapped_type> value;
  node* left;
  node* right;
};
みたいな感じのノードを持ってて、挿入や削除があるたびに、
与えられた比較関数なりファンクタなりの結果をもとにleft, rightのアドレスを付け替えてるんだ。
valueはキーと値のセットなわけだから、secondが大丈夫なのにfirstがダメってことは無い。
553デフォルトの名無しさん:2007/11/03(土) 21:31:34
俺はKeyへのポインタリストをもってて、ポインタリストは vector<void*> って感じにできてるんだと思ってたわ・・・
ちがかったのか・・・
554デフォルトの名無しさん:2007/11/03(土) 22:58:23
その辺の設計思想は、typedefにも表れてるんじゃないかな。
vector<T>::value_typeはT、list<T>::value_typeもTだけど、
map<Key, T>は、Keyがkey_typeでTがmapped_type、肝心のvalue_typeはpair<const Key, T>だから。
つまり、pair<const Key, T>型こそが「mapの値」の地位にあるわけ。
555デフォルトの名無しさん:2007/11/04(日) 01:13:11
STLの各種コンテナのend()が返す要素って中身をセットしても大丈夫なものなの?
vectorはあからさまにだめそうだけど、setやlistあたりはNullObjectとして空の要素を確保してたりするのかな。

↓こんな感じのことって有り?
map<Key, Value> map_;
map.end().second = Value(...); // キーが見つからないときのデフォルト値
556デフォルトの名無しさん:2007/11/04(日) 01:13:58
>>555 だめです。
557デフォルトの名無しさん:2007/11/04(日) 02:09:33
>>556
こんな深夜にありがとう。
558デフォルトの名無しさん:2007/11/04(日) 05:57:44
いってことよ
559デフォルトの名無しさん:2007/11/04(日) 10:08:05
プログラマに深夜も早朝もない
560デフォルトの名無しさん:2007/11/04(日) 12:42:30
しかしなんだな、新しい言語を習得する時って俺の場合、良書が必要なのだが
さっき『Effective C++第3版』と『Effective STL STLを使いこなす50の鉄則』を
書店で立ち読みしていて、どっちを買うか迷ったが結局両方買ってしまった
しかしコンピュータ関連に限らないけど専門書って高いよね。
そこで問題です。
v1とv2という2つのvectorがあるとする。v1をv2の後ろ半分と同じ内容にする最も簡単な方法は何だろうか。
v2の要素数が奇数であるときに「半分」をどう定義するかは気にせずに、妥当な方法を考えてほしい。
561デフォルトの名無しさん:2007/11/04(日) 12:54:24
// ???
std::vector<T>::size_type sz = v2.size()/2
v1.resize( v2.size() - sz );
std::copy_backward( v2.begin() + sz, v2.end(), v1.end() );
562デフォルトの名無しさん:2007/11/04(日) 12:58:54
>>560 v1.assign(v2.begin() + v2.size() / 2, v2.end());
563デフォルトの名無しさん:2007/11/04(日) 13:05:53
>>560
ふふふ さっそく(Effective STLを)つかっているな
564デフォルトの名無しさん:2007/11/04(日) 13:08:40
>>560です
>>562
最優秀賞を差し上げます。
560も『Effective STL STLを使いこなす50の鉄則』読んだのか、
因みに
>>561の解答は明示的にループは使ってないから、一見効率よさそうに見えるが
std::copy_backwardの中でループ処理を行うのでassignより効率は悪い。
565デフォルトの名無しさん:2007/11/04(日) 13:13:28
>>563
>>560です
いい本ですねこの本、STL本で最初に買ったのが、ハーバート・シルトの
STL標準講座だったんだけど、基礎的な用法しか書いてなかった、
実用的なのはEffective STLのだね。
566561:2007/11/04(日) 13:14:19
oops
567デフォルトの名無しさん:2007/11/04(日) 13:21:40
>>564
561 の効率が悪いのはループ云々じゃない。内部でループするかしないかって話なら
assign() でもしてるはず。

本質的な違いは、「デフォルト初期化+初期値代入」と「初期値で初期化」の違い。
568デフォルトの名無しさん:2007/11/04(日) 13:30:09
>>567
∈( ̄o ̄)∋ ホーッなるほど
569462:2007/11/06(火) 17:54:06
>>547

この短期間に二回も引越していてレスが出来ませんでした。あれから

r_iter = edge->atTime.rbegin(); // line 103

edge->atTime.erase((++r_iter).base()); // line 104

とやってみたのですが、以下のようなエラーが出ます:



node.cpp: In member function ‘void Node::backAndForth(int)’:

node.cpp:104: error: no matching function for call to ‘std::multimap<int, TIMESTRUCT, std::less<int>,
std::allocator<std::pair<const int, TIMESTRUCT> > >::
erase(std::_Rb_tree_const_iterator<std::pair<const int, TIMESTRUCT> >)’

以下略


make: *** [node.o] エラー 1



edge->atTime.erase(r_iter);でもほぼ同じエラーが出ます。

構造体を使ってしまったから普通の方法ではダメなのでしょうか?
570デフォルトの名無しさん:2007/11/06(火) 18:27:07
>>569
エラーメッセージをよく見て。
atTime が const っぽい。
571462:2007/11/07(水) 07:33:48
毎度ありがとうございます。m(__)m

本からのコピペだったので無意識のうちにconst_reverse_iteratorを使っていました。
普段からconst付ける癖がないのでこういう目に遭うんですね、きっと。

今日は>>535-536さんの忠告が今頃になって役に立ちました。
結果が0にならないといけないところが1.2345678e-318みたいになっていて
KDevelopでデバッグしたところ、rend()の値をコピーしていたのが原因と分かりました。
忠告がなかったら今でもデバッグ中だったと思います。
更に精進致します。
もっと時間があれば本を読むんですけどね…
あ、前回、C++本の付録で勉強していると書きましたが、実際は24章あるうちの1章でした。
ま、STL本じゃないのは確かです。
572デフォルトの名無しさん:2007/11/07(水) 21:09:48
オテレータ
573デフォルトの名無しさん:2007/11/13(火) 17:25:58
vector の内容を ランダムに順番を変える方法はあるでしょうか?
逆順は reverse() で、できたのですが;
574デフォルトの名無しさん:2007/11/13(火) 17:28:53
>>573
random_shuffle()
575デフォルトの名無しさん:2007/11/14(水) 02:23:36
>>574
ありがとうございます。STL ってすごいですね。
自前で作るより、極力あったら使おうと思って、聞いてしまいました。
576デフォルトの名無しさん:2007/11/14(水) 22:23:23
random_shuffleは厳密なランダムシャッフルではないから注意しる。
具体的には、random_shuffle前と全く同じ並びになることがない。
麻雀だのトランプだの選曲順だのならそれで問題ないとおもうが、
並び替える個数が少ない場合は問題になると思う。
577デフォルトの名無しさん:2007/11/14(水) 23:11:45
>>576
まったく同じならびにならないという根拠をkwsk
少なくとも自分の環境のrandom_shuffleのコードでは、
そんなわけのわからん現象は発生しないかった。
578デフォルトの名無しさん:2007/11/15(木) 01:27:16
GCC4で実験したが、同じ並びは発生した。

それよりも、第三引数を省略すると、結果が毎回一緒で使い物にならん。
579デフォルトの名無しさん:2007/11/15(木) 01:43:18
>>576 それ VC6 の実装のバグじゃないの?
580デフォルトの名無しさん:2007/11/15(木) 21:44:35
>>576が言っているのはこれのことなのかな?
ttp://ray.sakura.ne.jp/tips/shaffle.html
の1番下
581デフォルトの名無しさん:2007/11/17(土) 10:51:31
> 25.2.11 Random shuffle
> Complexity: Exactly (last - first ) - 1 swaps.

要素数が2の場合、必ず交換されることにならないか?
582デフォルトの名無しさん:2007/11/17(土) 11:28:06
同要素に対するswapが発生すれば良い
583デフォルトの名無しさん:2007/11/17(土) 11:34:21
>581
>580 の URL にある「改善策」の swap 回数はそうなってる。
584デフォルトの名無しさん:2007/11/17(土) 12:51:09
listに二分探査したらO(nlogn)な気がするんだけど、どうなんだろ?
オーダー的には特化で線形探査でもしてくれたらいいんだけど、
微妙に意味が違うからやってくれなさそう。

そもそもlistで整列データ管理すんのがお門違いなんだけどw
585デフォルトの名無しさん:2007/11/17(土) 15:28:46
なんだVCのバグか
じゃあ安心して使えるな
586デフォルトの名無しさん:2007/11/17(土) 16:02:53
>>584
イテレータのインクリメント・デクリメントが比較関数に対して無視できるほど軽いとすれば
O(log n) といえるんじゃないだろうか?
587デフォルトの名無しさん:2007/11/17(土) 16:04:57
>>581
その通り
588デフォルトの名無しさん:2007/11/17(土) 17:40:08
>>587 >>582 な、念のため。
589デフォルトの名無しさん:2007/11/17(土) 17:57:24
boostのドキュメント読んでよくでてくる
・Model
・Concept
・Refinement
ってSGIのリファレンスに載ってるんでしょうか?
なんかSTLを使うのに関してかなり重要な概念らしいんですが、全然意識してなかったので気になります
590デフォルトの名無しさん:2007/11/17(土) 18:53:45
591デフォルトの名無しさん:2007/11/18(日) 00:59:03
>>584
それが std::map。

592デフォルトの名無しさん:2007/11/18(日) 09:47:54
set
593デフォルトの名無しさん:2007/11/19(月) 22:49:34
まず、vectorってcontentsのアドレスの連続性が規格で保証されてるんですよね?
でもサイズとか増やせちゃうわけじゃないですか。
でメモリのアドレスが連続になるような確保って一括で確保しなきゃらならないですよね?
と言うことはcapacityが変わる時って変化後の容量分一括確保してそこに変化前の値をコピーして元データを削除
とかやってるんでしょうか?

なんかVCに付属のソース見ても何やってるのかいまいちわからないと言うか、
アンダースコアとかマクロだらけで読む気がなくなるというかで疑問のままなんです
594デフォルトの名無しさん:2007/11/19(月) 22:51:07
>>593
その理解で合ってる
595デフォルトの名無しさん:2007/11/20(火) 16:04:26
vector の検索について質問です。

typedef pair<int,int> AA;
vector<AA> v;

にて、v要素の firstに対して検索したいのですが
どのようにすれば良いでしょうか?

find_if()を試してみたのですが、私の力ではpairの組みで一致
するところまでしか出来ませんでした。

p = find_if(v.begin(), v.end()
      , bind1st( equal_to<AA>(), AA(10,15) ) // 本当はsecond無視で first==10を見つけたい
   );
596デフォルトの名無しさん:2007/11/20(火) 18:56:38
それpairでやる意味あるの?
intふたつ持った構造体に比較関数定義した方がよくないか?
597デフォルトの名無しさん:2007/11/20(火) 19:12:23
それはmapを使うところなんじゃないかな
598デフォルトの名無しさん:2007/11/20(火) 19:14:18
{
  typedef std::pair<int,int> AA;
  std::vector<AA> v;
  struct Comp {
    int m_i;
    Func(int i) : m_i(i) {}
    bool operator()(AA const& i) const {
      return i.second == m_i;
    }
  };
  
  v.push_back(std::make_pair(10,15));

  std::vector<AA>::iterator p = std::find_if(v.begin(), v.end(), Comp(15));
}
STLの範囲で、boost::lambda使わなきゃこんな感じ??
使えば次のようになる
find_if(v.begin(), v.end(), bind(&AA::second, _1) == 15 );
599595:2007/11/20(火) 19:49:48
早速有難う御座います。

>>596-597
リスト位置と内容、この3つの値を使うリストということで
ご了解いただければ。 

>>598
なるほど。比較構造体を作るわけですか。
参考にさせていただきます。有難う御座いました。
600デフォルトの名無しさん:2007/11/21(水) 06:25:16
キリ番取らせたら日本一の俺様が>>600を戴きます
601デフォルトの名無しさん:2007/11/21(水) 13:50:49
比較構造体?
602デフォルトの名無しさん:2007/11/21(水) 14:18:57
>>599
比較構造体ではなく関数オブジェクト、もしくはFunctorと言え。
603デフォルトの名無しさん:2007/11/22(木) 08:41:14
ふぁんくた!
604デフォルトの名無しさん:2007/11/22(木) 22:06:08
>>602
さぁ、算符を書く仕事にもどるんだ
605デフォルトの名無しさん:2007/11/23(金) 17:03:12
>>602
課長が呼んでたぞ
606デフォルトの名無しさん:2007/11/24(土) 03:31:06
struct comp
→直訳=比較構造体
607デフォルトの名無しさん:2007/11/24(土) 04:45:08
略して strcmp
608デフォルトの名無しさん:2007/11/24(土) 15:18:07
そういうことか!
609デフォルトの名無しさん:2007/11/24(土) 15:41:31
初めて知った
610デフォルトの名無しさん:2007/11/24(土) 17:56:58
メモメモ
611デフォルトの名無しさん:2007/11/24(土) 19:26:59
struct -ing
→string
612デフォルトの名無しさん:2007/11/24(土) 20:50:15
struct -ip
→strip
613デフォルトの名無しさん:2007/11/24(土) 21:30:07
ドラエモン マイナス エモン プラス ムカン
を思い出したが、たぶん知ってる奴はあまり居ない
614デフォルトの名無しさん:2007/11/24(土) 21:48:34
フク マイナス ク プラス ロ
615デフォルトの名無しさん:2007/11/24(土) 22:00:33
おまんじゅう マイナス じゅう プラス た
616デフォルトの名無しさん:2007/11/25(日) 11:33:29
もういいでしょ
617デフォルトの名無しさん:2007/11/25(日) 15:33:55
>>602
おやおやおや〜?
618デフォルトの名無しさん:2007/11/25(日) 17:30:24
教えてください
class Foo {
 vector<string> vec;   //これはOK
 vector<string> vec(5); // error C2059: 構文エラー : '定数'
public:
 Foo();
 ~Foo();
};

クラスのメンバ変数に固定長のコンテナを作るとエラーになるのはなんで?
619デフォルトの名無しさん:2007/11/25(日) 17:36:54
C2059: 低脳エラーです。今すぐC++はやめて下等な言語を使用してください。
620デフォルトの名無しさん:2007/11/25(日) 17:37:49
>>618
初期化はそんなところに書けない
コンストラクタに書く

Foo::Foo() : vec(5)
{
}
621デフォルトの名無しさん:2007/11/25(日) 17:59:29
>>620サンクス
もう一つだけお願い
typedefした場合の初期化はこれでOK?

class Foo {
 typedef vector<string> vec;
public:
 Foo();
 ~Foo();
};

Foo::Foo()
{
 vec(5);
}
622デフォルトの名無しさん:2007/11/25(日) 18:04:56
>>621
何をしたいのかワカンネ
623デフォルトの名無しさん:2007/11/25(日) 18:18:58
STL関係ねーな
624デフォルトの名無しさん:2007/11/25(日) 19:11:05
C++ですらないもんな
625デフォルトの名無しさん:2007/11/25(日) 20:09:41
まぁ、初心者スレに逝っとけと。
626デフォルトの名無しさん:2007/11/25(日) 21:16:43
日本語(UTF8)(ひらがな、感じ含む)文字列のソート処理をSTLのコンテナと
アルゴリズムを使って可能でしょうか?可能な場合どうすれば良いでしょうか?
627デフォルトの名無しさん:2007/11/25(日) 21:21:41
>>626
できそう。ソート順が望むものになるかどうかわかんないけど。
っていうか、自分で試してから相談しろよ。できそうにないと思うならその理由付きでな。
628デフォルトの名無しさん:2007/11/25(日) 22:12:04
結果はともかくとりあえずソートするだけなら
通常のASCIIと同じやり方で問題なし
629デフォルトの名無しさん:2007/11/26(月) 00:40:53
>>621
その場合のFoo::vecは型だ。
インスタンスに初期化を施すという常識をぶち破って型に対して初期化なんてもう訳が分からない。
それで何をしようとしている?vec(5)は単に、使えないvector<string>のインスタンスを作っているに過ぎない。
もし有用な閃きでもしたんなら、びょーんすっぽすっぽに直に談判してこい。
630デフォルトの名無しさん:2007/11/26(月) 01:51:51
 〆⌒ヽ
(#‘д‘) < だ、だれがハゲやねん!
    ∪ l| ||
     @ノハ@ =3 ペシッ!!
631デフォルトの名無しさん:2007/11/27(火) 21:42:51
const なメンバを持つようなクラスは
operator = をうまく定義できませんよね?
(コピーコンストラクタは定義できますが)
ということはコンテナには入れることができないということでしょうか?
632デフォルトの名無しさん:2007/11/27(火) 22:17:10
それは自分の作ったクラスに関して、自分で意味付けしていく領域。
633デフォルトの名無しさん:2007/11/27(火) 22:54:42
operator=でconstメンバを無視すればいい話じゃん。
634デフォルトの名無しさん:2007/11/27(火) 23:50:52
うまく定義できないってなんだ?
定義すればいいだろ
635デフォルトの名無しさん:2007/11/28(水) 00:36:20
shared_ptrなんかをコンテナの要素にすればいい(という場合もある)。
636デフォルトの名無しさん:2007/11/28(水) 01:24:12
質問なんですが、
wstringにはコピーコンストラクタは実装されて
いるのでしょうか?

関数にパラメータでwstringのインスタンスを
渡したら、実行時エラーになってしまいます。
637デフォルトの名無しさん:2007/11/28(水) 01:28:52
>>636
wstring はコピーコンストラクタでコピーを生成できる。

問題が再現する最小のソース作ってみて。
できたら、使ってるコンパイラも添えて貼ってみてほしい。
638デフォルトの名無しさん:2007/11/28(水) 07:19:49
>>637
コンパイラ :Visual Studio 2005 Express Edition

#include <iostream>
#include <string>
using namespace std;

wstring display(wstring path){
wstring work = path;
int i;

//パスの最後の\の位置を調べる
i = work.find_last_of(L'\\');

//それより後の部分を取り出す。
work = work.substr(i + 1, work.size());

return work;
}

int main(){
wchar_t *org = L"origi\\nal";
wstring *worg = new wstring [1];

worg[0] = org;

wcout << display(worg[0]) << endl;

return 0;
}

よろしくお願いします(^人^)
639デフォルトの名無しさん:2007/11/28(水) 08:04:46
>>638
VS2005EE で試してみたけど、 "nal" って表示されて終わった。エラーは出ない。

エラーメッセージは?
640デフォルトの名無しさん:2007/11/28(水) 08:10:10
> work.substr(i + 1, work.size());

work.size() にしてるのは問題ないんだっけ?
というか最後まで取り出すなら work.substr(i+1) でいいよね。
641デフォルトの名無しさん:2007/11/28(水) 08:11:19
wstring display(wstring &path)
じゃなくて
wstring display(wstring path)
なんだよね

っつーことは
wstring work = path;
より前に既に関数呼び出しの時点で
引数渡しのためにコピーコンストラクタが(ry
642デフォルトの名無しさん:2007/11/28(水) 08:18:51
i = work.find_last_of(L'\\');

i = work.find_last_of(L"\\");
643デフォルトの名無しさん:2007/11/28(水) 08:32:20
VC2005EE で
wchar_t *org = L"origi\\n表al";
で試したら
n
しか出力されませんでした

本当にありがとうございました

644デフォルトの名無しさん:2007/11/28(水) 08:53:26
wcout.imbue(std::locale("japanese"));
くらいしろと
645デフォルトの名無しさん:2007/11/28(水) 09:23:59
>>644
locale に渡せる言語の一覧ってどこ?
646デフォルトの名無しさん:2007/11/28(水) 09:41:19
MSならこれ
http://msdn2.microsoft.com/ja-jp/library/39cwe7zf(VS.80).aspx
Linuxならlocaleコマンド
647デフォルトの名無しさん:2007/11/28(水) 12:42:48
>>646
ふぅむ、それは処理系というかライブラリ依存なのか。
もっと、なんつーか、ISO とか IANA で決まってるのかと思ってた。
648デフォルトの名無しさん:2007/11/28(水) 17:35:52
そこがC/C++らしさだけど、使う気を失せさせるのは確か。
主要なライブラリベンダ同士でC/C++標準とは別に取り決めでもしてくれればいいのにと思う。

ちなみに""と"C"だけはどの処理系でも使えると決まっている。
649デフォルトの名無しさん:2007/11/28(水) 18:59:29
それが POSIX なんでは?
650デフォルトの名無しさん:2007/11/28(水) 19:05:52
そうなんだよ。だけど、Win32サブシステムの
普通のWindowsアプリケーションに適用できないのが痛い。
651デフォルトの名無しさん:2007/11/28(水) 19:07:13
POSIX には "" と "C" に加えて "POSIX" ロケールがあるが、他は実装依存
652デフォルトの名無しさん:2007/11/28(水) 20:15:57
Linuxのってことはlibstdc++だろうけど、以前コードを見たときには
ろくすっぽ実装されてなかったような……
653デフォルトの名無しさん:2007/11/28(水) 21:54:01
商用UNIXならまともなんだけどね。
654デフォルトの名無しさん:2007/11/29(木) 19:17:53
reverse_iterator とか const_reverse_iterator を使うと
なぜか Visual Studio では IntelliSense がしぬ.
655654:2007/11/29(木) 19:55:22
もっと限定された状況だった.
std::list<T>::reverse_iterator
std::list<T>::const_reverse_iterator
これを使うと以降 IntelliSense がしぬ.
656デフォルトの名無しさん:2007/11/29(木) 20:07:51
IntelliSenseを捨ててからC++は始まる
657デフォルトの名無しさん:2007/11/29(木) 23:53:48
Boostバリバリ使おうと思ったらIntelliSenseなんて既に死んでるぜ。
658デフォルトの名無しさん:2007/11/29(木) 23:57:50
>>655
2008でもそうなん?
659デフォルトの名無しさん:2007/11/30(金) 00:13:20
C++という言語自体、コンパイラ以外(場合によってはコンパイラすら)
による解釈を激しく拒むタイプの文法構造になってるというのは有名な話だな
660デフォルトの名無しさん:2007/11/30(金) 01:38:52
は?
661654:2007/11/30(金) 07:04:50
>>658
英語版 Visual C++ 2008 Express Edition では生きた.
662654:2007/11/30(金) 07:05:22
>>657
しかしそろそろ c++0x の auto が無いと死にそうな予感.
663デフォルトの名無しさん:2007/12/01(土) 11:10:41
max_elementアルゴリズムって、構造体型の要素を持つvectorにも使えますか?
typedef struct data {
string yymmdd;
 int code;
double openprice;
} data;

vector<stockdata> workcontainer;
...データを入れたとして...

この様な構造体の要素を持つベクトルのopenpriceの最大値を求めるのに
double max = max_element( workcontainer.begin()->openprice,
workcontainer.end()->openprice );
としたら

error C2100: 間接指定演算子 (*) の使い方が正しくありません。
となるんですが、何処が間違ってますか?
664デフォルトの名無しさん:2007/12/01(土) 11:22:44
>>663
呼出しが間違い。
max_elementにはiteratorを渡すこと。
665デフォルトの名無しさん:2007/12/01(土) 11:32:05
>>663
このスレでは割とよくでる質問らしいけど、
比較用の関数オブジェクトを用意してやるとうまくいくみたい
STLの関数等にどんな型のオブジェクトを渡してやればいいかは
ttp://www.sgi.com/tech/stl/を参考にすれば概ね問題無いようだ

#include <algorithm>
#include <string>
#include <vector>
#include <cassert>

struct data {
  data(double d) : openprice(d) {}
  std::string yymmdd;
  int code;
  double openprice;
};
bool compare(data const& lhs, data const& rhs) {
  return lhs.openprice < rhs.openprice;
}
int main() {
  std::vector<data> v;
  v.push_back( data(0.01) );
  v.push_back( data(0.1) );
  v.push_back( data(0.2) );
  double max = std::max_element(v.begin(), v.end(), &::compare)->openprice;
  assert( max == 0.2 );
}
666デフォルトの名無しさん:2007/12/01(土) 12:20:32
>>665先生デキマシタ+。:.゚(嬉´Д`嬉)゚.:。+゚ わぁい♪
>>このスレでは割とよくでる質問らしいけど、
そうなんですか、漏れも一般的な2ちゃんねらーということですねww
ところで、一点質問お願いします
初期化子で
data(double d) : openprice(d) {}
このように書かいてもらいましたが
自分は最初下記のように書いてたのですが、これでもOK?
openpriceはdouble型即ち、組込み型なのでいいと思うのですが、いかがなものでしょうか?
struct data {
  std::string yymmdd;
  int code;
  double openprice;
  stockdata() : yymmdd(""), code( 0 ), openprice( 0.0 ){}
};
667デフォルトの名無しさん:2007/12/01(土) 12:38:56
上の例では生成と同時にdata::openpriceに値を設定したかったから、それを実現するコンストラクタを用意しただけ
どんなコンストラクタを用意するべきかは「どんな初期化をしたいか」によるから、
「組み込み型はデフォルトで0って初期化もありでしょう」ぐらいしか言えない
668デフォルトの名無しさん:2007/12/01(土) 12:45:31
>>667先生( ̄〜 ̄;)ウーン・・・ 深いデツネ
>>上の例では生成と同時にdata::openpriceに値を設定したかったから
ってことは、
data() : yymmdd(""), code( 0 ), openprice( 0.0 ){}
これでは、生成と初期化が同時に出来ないということなんですね(自分では出来てるつもりだった^^;)
メイヤー先生の本をもう一回読み直して出直します。
ありがd
669デフォルトの名無しさん:2007/12/01(土) 15:11:59
std::multimap に対しては std::sort を適用できないですよね?
そもそも map/multimap に対してソートって意味ないような気もしますが,
map/multimap 同士に std::includes を適用したいことはあると思うのです.
しかし std::includes はソート済みのコンテナ同士に対してしか
適用できません.

std::multimap<int,int> multimap1;
multimap1.insert(std::pair<int,int>(1,2));
multimap1.insert(std::pair<int,int>(1,3));
multimap1.insert(std::pair<int,int>(2,5));

std::multimap<int,int> multimap2;
multimap2.insert(std::pair<int,int>(2,5));
multimap2.insert(std::pair<int,int>(1,2));
multimap2.insert(std::pair<int,int>(1,3));

のような二つの multimap に対して std::includes を適用した結果は
true になりますが,たとえば

std::multimap<int,int> multimap2;
multimap2.insert(std::pair<int,int>(2,5));
multimap2.insert(std::pair<int,int>(1,3));←ここがちがう
multimap2.insert(std::pair<int,int>(1,2));←ここがちがう

とすると false になります.Visual C++ 2008 でデバッグバージョンで
ビルドすると STL の内部のアサーションで「ソートされてない」
として実行が中断されます.かといって

std::sort(multimap2.begin(), multimap2.end());

はコンパイルできません.
multimap 同士で STL の集合演算を行うことはできないのでしょうか?
670デフォルトの名無しさん:2007/12/01(土) 16:27:31
>669
同じキーに対する要素間でのソート基準が規定されてないから。
multimap 以外は使えるんじゃない?
671デフォルトの名無しさん:2007/12/01(土) 17:14:46
そういう風にしたいのだったら、キーと値の両方がソートされた状態になるように、
multimapではなくstd::set<std::pair<int, int> >にでもするほうがいいと思う。
672デフォルトの名無しさん:2007/12/02(日) 07:01:20
JavaやC#を先にやったので、オブジェクトをコピー渡しして格納が基本の
STLのvectorやmapが凄く効率悪いような気がしてならないんですが、
そのへん、どう考えたらいいんでしょう?

一応自分なりに考えて見たんですが↓、正解有ります?
(1) C++は全般的にJavaやC#より速いので、気にするのは無益。
(2) 熟練プログラマはオブジェクトへのポインタを格納するのが普通なので速い。
(3) 熟練プログラマはshared_ptrを使うのが普通なのでC#と同等。
673デフォルトの名無しさん:2007/12/02(日) 08:28:25
たとえば、物凄くサイズの大きい型を、物凄い頻度でソートしまくる必要がある場合、
vector<T>じゃなくてvector<T*>を選ぶことはある。
でも、Tがポインタと同サイズだったら、コピーのコストは変わらず、読む速度はむしろ速いわけで、
STLはこっち、つまり「最速を叩き出す道を仕様によって閉ざさない」ことのほうを重視してる。

あと、mapはコピー渡しのコストとはあまり関係無いはず。
大抵、mapが持っているのは
struct node {
 pair<key_type, mapped_type> value;
 node* prev;
 node* next;
};
みたいなノードで、挿入や削除のたびにポインタを付け替えてるだけだから。
674デフォルトの名無しさん:2007/12/02(日) 11:30:04
>>639
---------------------------
wstring.exe - アプリケーション エラー
---------------------------
"0x7c950de3" の命令が "0xffffffff" のメモリを参照しました。メモリが "read" になることはできませんでした。


プログラムを終了するには [OK] をクリックしてください
---------------------------
OK
---------------------------

実行するとこのようなダイアログが出ます。。
675デフォルトの名無しさん:2007/12/02(日) 11:50:29
>>672
C# で値・参照型 ( struct/class ) を検討する場合を考えたら良いと思う。
データがポインタサイズ以下である事が多いなら、>>673 の書いているとおり、
コピーの方が速く、逆ならば参照型 ( Copy On Write )で設計した方が良い。
(2)、(3) の方法だと、データを使用する側でコストを意識する必要があるが、
データ型が予め適切な型 ( 値・参照 ) として設計されていれば、使用側は単純
なコピーだけ考えれば良いし、後に値・参照を切り替えたくなった時でも、
データ型の内部実装を変更するだけなので、メンテナンスコストも低くなる。
676デフォルトの名無しさん:2007/12/02(日) 12:16:26
>>674
>>638のコードコンパイルに成功して、実行できたぞ?
"0x7c950de3" の命令が "0xffffffff" のメモリを参照しました。メモリが "read" になることはできませんでした。
はいわゆる、メモリ保護違反のことだ
これ豆知識な
677デフォルトの名無しさん:2007/12/02(日) 12:27:14
>673 >675
参考になります。
ちなみに、C#で値型・参照型の使い分けは、経験的に16byteぐらいが目安とか
MSの中の人がMSDNかどこかで書いてました。
C++でもポインタサイズ(+α)の目安が有りそうですね。
678デフォルトの名無しさん:2007/12/02(日) 12:30:32
>>677
一応boostにptr_vectorってのがあるぞ。
std::vectorをそのまま置き換えるだけじゃうまくいかない部分もあるらしいけど。
679デフォルトの名無しさん:2007/12/02(日) 13:01:59
>>676
IDEからコンパイルしてますか?
コマンドラインからコンパイルしてますか?

私はIDEからコンパイルしているんで、同じようにIDEから
コンパイルしているなら、私のIDEの設定がどこかおかしいようですね・・

IDEの設定なんか項目数が多すぎてどうやって比較したらいいんだろ・・
680デフォルトの名無しさん:2007/12/02(日) 13:18:51
>>IDEからコンパイルしてますか?
うん
>>IDEの設定なんか項目数が多すぎてどうやって比較したらいいんだろ・・
文字セット、プリコンパイルの設定くらいかな、自宅のPCの場合
仕事だとライブラリィ関係のパスやMFCだとDLLリンクかスタティックリンクあたりも
気にするが?
681デフォルトの名無しさん:2007/12/02(日) 14:50:33
>>679
substrの第2引数は取り出す長さだから原因は>>640だろ。
682679:2007/12/02(日) 15:56:50
私のBuildLogです。
http://www.katsakuri.sakura.ne.jp/src/up29579.bin.html

拡張子が変わってしまったんでhtmlに直してもらえたら見えます。
比較してみたいので、よかったら、BuildLogをupしてもらえないでしょうか?

おそらくBuildLogを比較すれば設定の差異が分かると思うので。。

>>681
状況は変わりませんでした。
683デフォルトの名無しさん:2007/12/02(日) 16:13:31
デバッガでどこで落ちてるか調べた方が早い
684デフォルトの名無しさん:2007/12/02(日) 16:23:02
>>682
680だけど
http://www.katsakuri.sakura.ne.jp/src/up29580.bin.html
BuildLog、Upしたよ
ていうか激しくスレちがいな気もするが^^;
因みにおいらはVS2005のProですが変わらんと思うよ
685デフォルトの名無しさん:2007/12/02(日) 16:28:38
>>672
基本2で,1も3も可能な柔軟性
686679:2007/12/02(日) 19:36:25
>>683
デバッガだと落ちないんです。

>>684
ありがとうございます!早速比較してみましたが、
特にこの問題にかかわるような差異は見つけられませんでした・・

VS自体を再インストールしてSP1を当ててみましたが、
結果は同じでした。

ちょっともう手に負えないので残念ですが諦めようと思います。
ありがとうございました;;
687デフォルトの名無しさん:2007/12/04(火) 12:32:35
std::logical_and のように、
bitwise で論理積をとってくれるファンクタは用意されていませんか?
自分で用意する必要があるでしょうか?

用意すること自体は簡単なんですが、
標準的なファンクタがあるならそちらを使ったほうがいいかと思って。

boost::mpl も探してみたんですが、 bitand.hpp はみつかったものの
どうも自分がいとしているものとは違うようです。
688デフォルトの名無しさん:2007/12/04(火) 16:52:01
あるファンクタ f1 の結果が新のときのみ
別のファンクタ f2 を適用したいと思っています。
これを実現する合成ファンクタを生成する簡単な方法があるでしょうか?
689688:2007/12/04(火) 19:01:24
boost wiki にある for_each_if を使うことにしました。
これが C++0x に入ってくれたりするんだろうか。
そもそも copy_if が標準にないし。
690デフォルトの名無しさん:2007/12/06(木) 17:18:24
mapは数字、大文字の英数、小文字の英数って順番でソートされていますよね?
これを、大文字と小文字を区別しない辞書順に変えたいのですが
どうすればいいでしょうか?
691デフォルトの名無しさん:2007/12/06(木) 17:34:17
大文字小文字を区別しない比較関数オブジェクトを作って、
mapのテンプレート引数3番目にデフォルトのless<T>の代わりに入れる
692デフォルトの名無しさん:2007/12/06(木) 18:14:39
たびたび失礼します。
そのようにした場合、大文字と小文字を区別しないと、例えばTESTとtestがあった場合にはtestが2つみたいになってしまうんですか?
そうならないようにしたいんです。
説明下手ですいません
693デフォルトの名無しさん:2007/12/06(木) 18:18:21
testとTESTを区別したいってことか?それなら
A < a < B < b < C < c ...
みたいな順序で辞書順にすれば良い。
694デフォルトの名無しさん:2007/12/06(木) 19:38:59
すいません、調べてみたんですがどうやってやったらいいか分かりません
教えていただけませんか?
695デフォルトの名無しさん:2007/12/06(木) 19:43:37
>>694
何を調べて結局何がわからなかったのかはっきりさせようよ。
・関数オブジェクトの作り方
・A < a < B < b < C < c ... の比較の仕方
696デフォルトの名無しさん:2007/12/06(木) 19:56:42
すいません。
関数オブジェクトの作り方から調べたんですがよく分かりませんでした。
比較の仕方も具体的にどうやればいいのか教えていただけると助かります。
697デフォルトの名無しさん:2007/12/06(木) 20:26:30
>>696
operator() を持つクラスを作るだけだよ。

struct comp
{
bool operator()(const string& s0, const string& s1)const {
// 比較
// s0 が s1 より小さい(先にくる)ならtrue, そうでなければfalseを返す
}
};

map<string, int, comp> hoge;

実際の比較処理はSTLの範囲外だし文字列処理の初歩なのでがんばってくれ
698デフォルトの名無しさん:2007/12/06(木) 20:36:12
>>692
>0そのようにした場合、大文字と小文字を区別しないと、例えばTESTとtestが
>あった場合にはtestが2つみたいになってしまうんですか?

ならないから、>>693>>695は無視して安心してください。
699デフォルトの名無しさん:2007/12/06(木) 22:58:27
class comp : public binary_function<string,string,bool>{
public:
bool operator()(const string& s1,const string& s2)const{
for(int i=0;i!=s1.length();i++)
toupper(s1[i]);
for(int i=0;i!=s2.length();i++)
toupper(s2[i]);
if(s1<s2)
return true;
else
return false;
}
};

いろいろ探しながらやってみたらこうなったんですけど
大文字の辞書順が先に出て、次に小文字の辞書順が出てきたままでした。
なにがいけないんでしょうか
700デフォルトの名無しさん:2007/12/06(木) 23:25:28
>>699
s1="abc"、s2="ABC" を入れたときの動作と
s1="ABC"、s2="abc" を入れたときの動作を考えてみろよ
それだとどっちも false が返ってくるじゃん
701デフォルトの名無しさん:2007/12/06(木) 23:29:39
>>696
調べたって、どういう風に調べたの?
「関数オブジェクト」で検索したら、定義と作り方が丁寧に書いてあるページばっか出てきたけど。
もしこれらを見てもわからなかったというのなら、つまりそれより詳細でわかりやすい説明を
このスレに書き込めって要求してることになるが、それは無茶というものだよ。
702デフォルトの名無しさん:2007/12/06(木) 23:49:30
class comp : public binary_function<string,string,bool>{
public:
bool operator()(const string& s1,const string& s2)const{
for(int i=0;i!=s1.length()||i!=s2.length();i++){
if(toupper(s1[i])<toupper(s2[i]))
return true;
else if(toupper(s1[i])>toupper(s2[i]))
return false;
}
if(s1<s2)
return true;
else
return false;
}
};

これでどうでしょうか?
703デフォルトの名無しさん:2007/12/06(木) 23:55:03
>>699
toupperの使い方がまるで違う

for(int i=0;i<s1.length() && i<s2.length();i++)
{
unsigned char c,d;
c=s1[i];
d=s2[i];
if(toupper(c)!=toupper(d)) return toupper(c)<toupper(d);
else if(c!=d) return c<d;
}
return s1.length() < s2.length();


試してないから合ってるから知らん
704デフォルトの名無しさん:2007/12/06(木) 23:56:15
stricmp は使わないの?
705デフォルトの名無しさん:2007/12/07(金) 00:06:18
lexicographical_compare使おうぜ。

struct mixcomp_char : public std::binary_function<char, char, bool>
{
  bool operator()(char x, char y) const
  {
    char lx = std::tolower(x);
    char ly = std::tolower(y);
    if(lx < ly) return true;
    if(lx > ly) return false;
    return x < y;
  }
};

struct mixcomp : public std::binary_function<std::string, std::string, bool>
{
  bool operator()(const std::string &x, const std::string &y)
  {
    return std::lexicographical_compare(x.begin(), x.end(), y.begin(), y.end(), mixcomp_char());
  }
};
706デフォルトの名無しさん:2007/12/07(金) 00:27:54
>>701
豆腐のカドにチンコぶつけて市ね
707デフォルトの名無しさん:2007/12/07(金) 06:16:49
>>706
で、どういう風に調べたの?
ここの住人を「ああ、こいつはちゃんと調べた上で質問してるんだな」と納得させられる調べ方は
まるでしてなかってことかな?
708デフォルトの名無しさん:2007/12/07(金) 22:13:51
>>707
分からないんなら出しゃばるなよ。
709デフォルトの名無しさん:2007/12/08(土) 05:57:30
>>708
で、どういう風に調べたの?
710デフォルトの名無しさん:2007/12/08(土) 12:22:08
最近はなんの保障もないweb上の情報など使わない
調べるだけ時間の無駄

本屋行ってみれば情報量の高い有益な情報が手に入る。
(なかには使い物にならないものもあるが)
711デフォルトの名無しさん:2007/12/08(土) 12:33:14
本屋に行く時間と金がもったいない貧乏人はweb
712デフォルトの名無しさん:2007/12/08(土) 13:05:03
本屋に入ったって結局本を選別する技術が必要。
ネットより比率がマシってだけで大して変わらん。
713デフォルトの名無しさん:2007/12/08(土) 13:41:23
>710
そういうセリフは英語を使えるようになってから言え。
714デフォルトの名無しさん:2007/12/08(土) 15:44:10
#include <algorithm>
#include <iostream>
#include <vector>
struct data {
data(int d) : num(d) {}
data(double db) : openprice(db){}
int num;
double openprice;
};
inline double comp(const data& lhs, const data& rhs) {
return lhs.openprice < rhs.openprice;
}
int main() {
std::vector<data> v;
v.push_back( data(1) );
v.push_back( data(0.1) );
v.push_back( data(2) );
v.push_back( data(0.2) );
v.push_back( data(3) );
v.push_back( data(0.3) );
double MAXOF = max_element(v.begin(), v.end(), &::comp)->openprice;
std::cout << MAXOF << std::endl;
return 0;
}
上記のコードではcomp比較関数でopenpriceの最大値を取得しているのですが、
openpriceの大小を比較して、戻り値としてその値と同じ構造体エレメントに属する
numの値を取得する場合の比較関数の書き方を教えてもらえないでしょうか。
(例えばこのコードの場合、3という値を望みます)
715デフォルトの名無しさん:2007/12/08(土) 15:49:24
>>714
比較関数はそのままで、
max_element(v.begin(), v.end(), &::comp)->openprice

max_element(v.begin(), v.end(), &::comp)->num
にすれば良い。

あと、そのコードは初期化のやり方がおかしい。
v.push_back( data(1) );
v.push_back( data(0.1) );
こうすると、
・num=1, openprice=不定
・num=不定, openprice=0.1
の二つのdataがvに入るが、意図としては
num=1, openprice=0.1
という一つのdataを入れたいんだよな?
716デフォルトの名無しさん:2007/12/08(土) 15:54:28
std::for_each の第三引数はなぜ値渡しなのでしょうか?
参照渡しのほうが内部状態を持ち続けたいときなどに
便利だと思うのでが.効率の面からですか?

もちろんファンクタが持つべき内部状態をカプセル化して
boost::shared_ptr などで持たせればいいのですが,
不思議に思ったので.
717デフォルトの名無しさん:2007/12/08(土) 16:01:07
>>716
単純に非 const 参照にすると、その場で生成したファンクタを渡せない。
const 参照にすると operator () に const が付いてないと使えない。

こんなとこじゃないの?
718714:2007/12/08(土) 16:23:27
>>715さん
どうもありがとうです、
>num=1, openprice=0.1
>という一つのdataを入れたいんだよな?
そうなんですが、これでいいのかな?
#include <algorithm>
#include <iostream>
#include <vector>
struct data {
  int num;
  double openprice;
  data():num(0), openprice(0.0){}
};
inline double comp(const data& lhs, const data& rhs) {
  return lhs.openprice < rhs.openprice;
}
int main() {
  std::vector<data> v(3);
  v[0].num = 1;
  v[0].openprice = 0.1;
  v[1].num = 2;
  v[1].openprice = 0.2;
  v[2].num = 3;
  v[2].openprice = 0.3;
  double MAXOF = max_element(v.begin(), v.end(), &::comp)->num;
  std::cout << MAXOF << std::endl;
  return 0;
}
でもこれだと、push_back()関数やイテレータを定義して、insert()関数での代入が出来
なくなるのかな?構造体が絡むと混乱してしまいます・
719714:2007/12/08(土) 16:25:32
失礼しました
×double MAXOF = max_element(v.begin(), v.end(), &::comp)->num;
○int MAXNUM = max_element(v.begin(), v.end(), &::comp)->num;
こうです
720デフォルトの名無しさん:2007/12/08(土) 16:30:39
>>718
引数を二つとるコンストラクタを作れば良い。
struct data {
    data(int n, double db) : num(n), openprice(db){}
    int num;
    double openprice;
};

...
v.push_back( data(1, 0.1) );
721デフォルトの名無しさん:2007/12/08(土) 16:32:16
二引数をとるコンストラクタを定義しないのかね
722デフォルトの名無しさん:2007/12/08(土) 16:40:47
>>718
本題と関係ないが、特に理由がないならcompはboolを返すべき
723714:2007/12/08(土) 16:54:31
>>720
>>721
>>722
みんなありがとう
724デフォルトの名無しさん:2007/12/08(土) 21:53:47
>>713
欧米のサイトは十分実用に耐えうるってこと?
725デフォルトの名無しさん:2007/12/08(土) 22:08:11
一次ソースは英語がほとんどだから、翻訳されたものよりは信頼性はあるんじゃね。
726デフォルトの名無しさん:2007/12/08(土) 22:36:56
本は良書だけピンポイントで買うもんじゃないか
普段の情報集めはwebで
727デフォルトの名無しさん:2007/12/08(土) 22:40:00
え?本てとりあえず目に付いたものを、
予算消化とクレカポイントとアマゾンポイント狙いで
立替払いで買うもんじゃないのか。
728デフォルトの名無しさん:2007/12/08(土) 22:52:31
俺はじっくり腰を据えるタイプだから、良書はなるべく買って読んでる
今はメイヤーズ先生のEffective STLを読んでる処だよ、先にSTL標準講座を買ったが
おさらい程度でざっくりと読んで、基本的なことで分からないことがあった場合、
付箋を貼りながら開いているな。
729デフォルトの名無しさん:2007/12/08(土) 23:08:01
画面を見つづけるより本を見るほうが疲れないし好きなんだけど、
本を見ながらコーディングするときって、どういう配置にすれば良いかいつも迷う。
今はキーボードの手前に本を置いて、キーボードを打つのと本を抑えるのを兼ねてるんだけど違和感ありすぎる。
730デフォルトの名無しさん:2007/12/08(土) 23:15:12
>>729
つ ほんたった

あんまり使ってないけど
731デフォルトの名無しさん:2007/12/08(土) 23:19:49
webでもいい情報はあると思うけど…
jisc.orgのJISX3014とかMSDNとか
732デフォルトの名無しさん:2007/12/08(土) 23:25:41
>>730
お、こんなのあるんだねー。
安いし試しに買ってみようかな。
733デフォルトの名無しさん:2007/12/09(日) 09:34:52
vector型の空コンテナに対してerase()関数を実行すると、
当然Assertionで落ちますけどこの例外がcatchできる、関数を教えてもらえないでしょうか?
734デフォルトの名無しさん:2007/12/09(日) 09:36:54
std::out_of_range じゃないの?
とか思い付きで言ってみる.

そんなことより,Java の Generic ってテンプレートと
同じくらい強力なものなの?教えてママ.
735デフォルトの名無しさん:2007/12/09(日) 10:56:17
> 23.2.4.4
> Throws: Nothing unless an exception is thrown by the copy constructor or assignment operator of T.

要素のコピーコンストラクタか代入演算子が例外投げなければ投げない
ってあるから、std::out_of_rangeは投げない。
存在しない要素のeraseは未定義動作。
736733:2007/12/09(日) 12:00:28
>>735
サンクス
ていうことは、空のvectorコンテナをerase()しないようにしないと、いけない訳で
要素が空か否か、判定するベターな方法は、どうしたらいいのかなぁ?
737デフォルトの名無しさん:2007/12/09(日) 12:06:12
>>736
つempty( )
738733:2007/12/09(日) 12:53:16
empty()は至極普通に、最初に試したんだけど、上手くいったり、いかなかったり(Assertion落ち)
なんだよね、今find()関数の比較演算子(==)をオーバーライドして、専用のクラス作って
何となく上手くいきそうな悪寒です、なんかさerase()やempty()で空のvectorコンテナ操作するときって
注意が必要だね。
739デフォルトの名無しさん:2007/12/09(日) 12:55:43
emptyで落ちるのはおかしい。
それ以前に内容が破壊されてるんじゃないか?
740733:2007/12/09(日) 13:02:57
>>739
そうかもね、STLでのデバッグはなちょいと読み辛いから、しんどいな・・・・
741デフォルトの名無しさん:2007/12/09(日) 13:08:44
> なんかさerase()やempty()で空のvectorコンテナ操作するときって注意が必要だね。

erase()はともかくempty()は注意する必要などないよな
742デフォルトの名無しさん:2007/12/09(日) 13:18:47
そうだな.
世の中には二つのコンテナしかない.
empty() か empty() でないか,だ.
743733:2007/12/09(日) 13:31:39
あ!そうか
std::vector<data> v;
std::vector<data>::iterator iter;
iter = v.begin();
iter += 2;
if(!v.empty())
・・・・・・

こんな感じで、コンテナの特定Elementの有無を判定している、つもりだったんだけど
やり方が不味かったのかな?
find()関数のいオーバーロードでロジックは完成したんだけど、empty()関数使って
コンテナがぶっ飛ぶってのが凄く薄気味悪い!?((((;゜Д゜))).
744デフォルトの名無しさん:2007/12/09(日) 13:37:56
>>743
そもそも何のコードを書いてて落ちるだの飛ぶだの言ってるの?

> iter = v.begin();
> iter += 2;
> if(!v.empty())

こことか何をしたいのか意味がわからないし、
> コンテナの特定Elementの有無を判定している
という表現もよくわからない
745デフォルトの名無しさん:2007/12/09(日) 13:38:52
iter += 2 の前に何とかしてほしい気もするが,
empty() で落ちるってのはなんかおかしいなぁ.
746733:2007/12/09(日) 13:41:45
iter = v.begin() + 2;
こいういう事?
747デフォルトの名無しさん:2007/12/09(日) 13:50:31
というか、iterをどうこうする前に、emptyチェックかけとけよ
748デフォルトの名無しさん:2007/12/09(日) 13:51:35
順番が違うよな。
emptyではないことを確認してから、beginとかを呼ぶんだよ。
749745:2007/12/09(日) 13:58:41
>>747-748
あー,そういうことを言いたかった.
言葉足らずでスマン.
750733:2007/12/09(日) 13:59:51
ざっくり言えば、構造体を要素にもつvector型のコンテナがあって、その構造体には
他のvectorや、自身(構造体)が何番目のキーが入力されて出来たデータとかの、
情報が入っています、まぁ管理テーブルのようなものと思った欲しい
なので、制約があって
1のキーを押下→v0番目に格納
2のキーを押下→v1番目に格納
3のキーを押下→v2番目に格納
4のキーを押下→v3番目に格納
5のキーを押下→v4番目に格納
6のキーを押下→v0番目に格納したベクトルを削除
7のキーを押下→v1番目に格納したベクトルを削除
8のキーを押下→v2番目に格納したベクトルを削除
9のキーを押下→v3番目に格納したベクトルを削除
10のキーを押下→v4番目に格納したベクトルを削除
こういう実装がしたかったわけよ、そこで最初vector
を固定長にしようとしたら、複雑になることに気付き、構造体に、何番目のキー入力で
出来たかって情報を付加し、削除する場合そのキーを検索して削除するってロジックに
落ち着いたって感じなんだよね、そこでキー入力後、管理テーブルベクターで
同じキー入力があった場合、はじくためにempty()を使いたかったんだけど、
上手くいかなかったんだよね
751デフォルトの名無しさん:2007/12/09(日) 14:00:58
iter += 2 でも begin() + 2 でも、その時点で既にコンテナ末尾(end())を超えてるんでやばいんじゃねーの、と言われてるんだよ。

>748
先に確認しとけ、とは思うけど、empty() でも begin() は呼んでも問題ないっしょ?
752デフォルトの名無しさん:2007/12/09(日) 14:04:52
>>751
ああ、まぁ、確かに。
end()の戻り値と同じものが呼ばれるだけで、扱いが正しければ害は無いよな。
753デフォルトの名無しさん:2007/12/09(日) 14:05:57
>750
さっぱり分からない。多分コード見せてもらった方が…、でもやっぱり分からん気もする。
とりあえず、v0 〜 v4 はそれぞれ vector なのか?、vector の特定の位置なのか?
そもそも vector である必要があるんか?なんとなく、map 使えば良さそうな気がするんだが。
754デフォルトの名無しさん:2007/12/09(日) 14:09:37
>>750
そういうのは関係無いと思う。
>>743のコードが問題なのは、「中身をいじり始めてから、中身があるかどうかを確認している」ところ。
それって、飛び降りてからパラシュートを付けてるかどうか確認するようなものだよ。
755デフォルトの名無しさん:2007/12/09(日) 14:34:54
>>750
たぶんvectorの使い方をわかってなさそうなので、もっとシンプルな構造でテストすべきだと思うよ。
756デフォルトの名無しさん:2007/12/09(日) 14:35:59
いつものことだが
もう全部貼れよw
757デフォルトの名無しさん:2007/12/09(日) 14:56:38
もし空だったらiter += 2この時点で鼻から悪魔
758デフォルトの名無しさん:2007/12/09(日) 15:13:08
どうせ iter += 2 の中で assert 失敗してるんだろ。
759デフォルトの名無しさん:2007/12/09(日) 17:12:13
>>743
凄く薄気味悪い って、おまえが凄く薄気味悪いコード書いてるからだよ。map使え
760デフォルトの名無しさん:2007/12/09(日) 22:13:38
同じ、データ同士をマージしたらどうなるの
やっぱ未定義動作?
761デフォルトの名無しさん:2007/12/09(日) 22:17:46
>>754
不謹慎ながらワロタwww
762デフォルトの名無しさん:2007/12/09(日) 22:26:47
>>760
何でやねん
mergeは重複要素を除外しない
set_unionは重複要素を除外する
それだけの違い
763デフォルトの名無しさん:2007/12/09(日) 23:49:30
vector <MyClass> array;

とした時に、array 中の指定した文字列と同じ文字列を持つ要素があるかどうかを調べる
関数を書きたいのですが、MyClass c ; とやって c との比較なら array.find()で出来るのですが
その中の一メンバー変数の比較をしなきゃならないんですが、このような場合はどうするのが
良いでしょうか?

764デフォルトの名無しさん:2007/12/09(日) 23:50:03
array 中の → array 中に
765デフォルトの名無しさん:2007/12/09(日) 23:54:07
>>763 std::find_if()
766デフォルトの名無しさん:2007/12/09(日) 23:55:47
763です。
Thx!
767デフォルトの名無しさん:2007/12/12(水) 23:33:26
find_if
768デフォルトの名無しさん:2007/12/16(日) 16:56:46
std::stackって、なんでstd::dequeのアダプタという形で実装されているんでしょうか?std::queueと違って配列末尾でしか要素の追加削除がされないのだから、vectorで実装してもよさそうですが。
stack作成時にテンプレートのパラメタでvectorを使うように指定できるのは知ってます。デフォルトがdequeになっている理由がわからないです。

769デフォルトの名無しさん:2007/12/16(日) 17:12:02
>>768
vector は再確保が発生するときのコストが大きい。要素数の上限が分かっていれば
reserve() した vector を使うのがいいんだろうけど、どっちかというと要素数に対する
前提が無くても極端な特徴の無い deque をデフォルトにしとくのは妥当なところだと思う。
知ってのとおり vector も選べるしね。
770デフォルトの名無しさん:2007/12/16(日) 17:20:46
>>769
回答ありがとう。

典型的なdequeの、内部で抱えているバッファって単純なchar配列1つではない?
1つのchar[]をリングバッファとして使っているだけかと思っていました。
771770:2007/12/16(日) 17:29:51
char[]はT[]の誤記です。
772デフォルトの名無しさん:2007/12/16(日) 17:37:50
>>770
ひとつの配列だと結局再確保が発生するときに O(n) になるから、計算量の要件が
満たせないでしょ。

STLport の実装見たら、固定サイズの配列を T* の配列で持ってた。
773デフォルトの名無しさん:2007/12/16(日) 18:23:36
>>772
えーと、メンバとして T** m_nodes; を持っていて、コンストラクタで
    m_nodes = new T*[3];
    m_nodes[0] = NULL;
    m_nodes[1] = new T[N];
    m_nodes[2] = NULL;
とかしておいて、push_front(x)されたらm_nodes[0]にもnew T[N]してやってそこに値xを覚えるとかでしょうか?

774デフォルトの名無しさん:2007/12/16(日) 18:46:13
>>773
特定の実装の詳細知りたければソース見れば? STLport だって言ってるんだし。
775デフォルトの名無しさん:2007/12/16(日) 19:05:31
>>772
vectorとdequeは末尾への要素追加に対する計算量の要求は同じで、vectorは配列で実装されているわけだが・・・
それについてはどうなの?
776デフォルトの名無しさん:2007/12/16(日) 19:40:06
>>775
vector の push_back は Sequence で定められる償却定数時間なのに対して
deque の push_back および push_front は定数時間とされている。

23.2.1 Class template deque の p1 より
> A deque is a kind of sequence that, like a vector (23.2.4), supports random access iterators. In addition,
> it supports constant time insert and erase operations at the beginning or the end; insert and erase in the middle
> take linear time.
777デフォルトの名無しさん:2007/12/16(日) 19:40:24
>775
deque:
Inserting a single element either at the beginning or end of a deque
always takes constant time and causes a single call to the copy constructor of T.

vector の方はあくまで amortized な。
778デフォルトの名無しさん:2007/12/16(日) 20:01:29
>>776-777
deque先頭末尾はamortizedではないのか。それ、厳密にやろうとするとlistにしないと無理だったりしない?
STLPortの方法が常にconstantとは思えないのだが。
779デフォルトの名無しさん:2007/12/16(日) 20:02:31
listでいいわけがない。。。。ランダムアクセスできないとだめだったorz
780デフォルトの名無しさん:2007/12/16(日) 20:06:46
俺もGNU libstdc++のソース見たけど、T *の配列を再確保するときに線形時間掛かるように見える
781デフォルトの名無しさん:2007/12/16(日) 20:10:13
>>777
適当にぐぐってみたが、
http://www.thescripts.com/forum/thread394684.html
http://www.hanecci.com/pukiwiki/index.php?Programming%2FC%2B%2B%2FSTL#ua0df688
このへんだと償却時間という解釈にしてしまっているね。

>>780
libstdc++については、
http://gcc.gnu.org/ml/gcc-bugs/2004-01/msg00028.html
ここで、not conformantでは?という投稿がされてる。これから読んでみる。

さて真相は。
782デフォルトの名無しさん:2007/12/16(日) 20:20:22
SGI STL http://www.sgi.com/tech/stl/Deque.html#2
だと、amortized constant time って明示してあるね。むぅ。
783デフォルトの名無しさん:2007/12/16(日) 20:21:06
>>781
>23.1/2 says, "All of the complexity requirements in this clause are stated
>solely in terms of the number of operations on the contained objects."
これは知らなかった。ポインタ操作は定数回じゃなくてもいいのか
784デフォルトの名無しさん:2007/12/16(日) 20:24:26
>>783
ぜひ結論をまとめてくれw
785デフォルトの名無しさん:2007/12/16(日) 20:31:48
>>783
そうらしいね。でもそんなこといったら list の size() だって定数時間って言えちゃいそうな
気もするなぁ。

http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#632
> We think that the complexity of the size() member of every container -- except possibly list -- should be O(1).
なんかおかしくね?
786デフォルトの名無しさん:2007/12/16(日) 20:36:48
newによるメモリ確保の計算時間って、規格ではどうしろっていってんの?
787デフォルトの名無しさん:2007/12/16(日) 20:42:10
>>768 たぶん、どうしろとも言ってない。
788デフォルトの名無しさん:2007/12/16(日) 20:48:26
>>784
コンテナの操作の計算量に関する要求は標準の23.1にあるわけだが、
ここで要求されている計算量は、操作に掛かる時間そのものについてじゃなくて、
「コンテナ内のオブジェクトを操作する回数」についてのものだと規定されてる
たとえばvectorに対するpush_backなら、要素のコピーコンストラクタを償却O(1)回呼ぶってことだ
で、libstdc++(たぶんstlportも)のdequeの実装だと、最悪O(n)回のポインタ代入が発生するけど、
要素のコピーコンストラクタは常に1回しか呼ばれないので、規格の要求するO(1)は満たしてることになる
789デフォルトの名無しさん:2007/12/16(日) 21:06:02
>>788 なるほど!
790デフォルトの名無しさん:2007/12/16(日) 21:22:14
>>785
list に operator [] つけてもおk・・・になっちゃうよねぇ。
791デフォルトの名無しさん:2007/12/16(日) 23:31:24
標準では vector<vector<int> > のコピーコンストラクタは O(N) ですよと言っているだけ
O(N×M) じゃないですよと

そのほかは常識的に考えようね
792デフォルトの名無しさん:2007/12/16(日) 23:39:32
日本語でおk
793デフォルトの名無しさん:2007/12/16(日) 23:43:08
委員会の意図がなんであろうと書かれていることが全てだろ
794デフォルトの名無しさん:2007/12/16(日) 23:49:03
std::listのsize()って線形時間かかるの実装が多いの?
サイズくらい4バイト程度なんだから変数で覚えとけとおもうんだけど。
795デフォルトの名無しさん:2007/12/16(日) 23:53:45
>>794
変数で覚えてても splice() されたら変わってしまう。
796デフォルトの名無しさん:2007/12/16(日) 23:55:12
サイズを覚えとくとspliceが定数時間でできなくなるから、トレードオフだな
797デフォルトの名無しさん:2007/12/17(月) 00:04:52
>>793
やっぱりある程度は常識で処理しないとだめなんじゃないかな
23.1/2 を常識的に読むと list<T>::operator[] が O(1) にはならない
798デフォルトの名無しさん:2007/12/17(月) 00:08:24
>795-796
どうもありがとう
799デフォルトの名無しさん:2007/12/17(月) 00:18:15
Effective STLには確か、どっちの実装もありうるから覚悟しとけ、と書いてあったな。
環境依存でよいなら実測汁。
800デフォルトの名無しさん:2007/12/17(月) 00:27:18
>>797
いや、常識的に考えると list<T>::operator[] は O(n) だけど、 23.1/2 を
(常識的にでもなんでも)読んでしまえば O(1) と言えると考えざるをえないでしょ。

で、何かおかしいって話だよ。漁ったらこんなん出てきた。
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1996/N0937R1.asc

あの記述が追加されたのは、要素型によっては実時間が定数時間にはならないという
問題を解決するため。つまり規格中の deque の要件がこの追記より前に定められていた
場合、単純に規格化の際に amortized を書き漏らした可能性があると。
>782 で挙げられた SGI のドキュメントに amortized が付いてることから考えても。
801デフォルトの名無しさん:2007/12/17(月) 00:27:36
>>797
俺にはそうは読めない
もしかしてそういう意図だったのかな、と想像することはできるけど
というか自分の主観を常識として語るのやめろよ
802デフォルトの名無しさん:2007/12/17(月) 00:38:40
さぁ、きな臭くなってまいりました
803デフォルトの名無しさん:2007/12/17(月) 00:41:36
wktk
804デフォルトの名無しさん:2007/12/17(月) 01:26:40
常識なんて言葉使ってるやつはたいがいハッタリ君
805デフォルトの名無しさん:2007/12/17(月) 03:18:31
red-black treeのiteratorってどうやって実装するんだろ
806デフォルトの名無しさん:2007/12/17(月) 18:49:21
おい>>799
俺も、かの有名なメイヤーズ先生が書いた、凄く薄っぺらの「Effective STL」を読んでいるが、、一向に脳内で咀嚼できず、前に進めない、
お前はどれ位で、この本を理解するのに、なん時間位かかった?
807デフォルトの名無しさん:2007/12/17(月) 20:22:17
現在策定中の次期標準仕様でコンテナの計算量についての記述は修正されてるの?
少なくとも 23.1/2 は N2461 でもそのままだけど
808デフォルトの名無しさん:2007/12/18(火) 02:28:55
>>807
修正というからには、まずどこが間違っているのか挙げてもらおうか。
809デフォルトの名無しさん:2007/12/18(火) 10:13:25
ここでいいのか迷いましたがこちらで質問させていただきます。
vectorの特定の要素へのイテレーターを返してほしいばあい、どうすればいいのでしょうか。

vector<double> vec;
vec.resize(100);
vector<double>::iterator it;

hogehoge();

double d = vec[12];
//double d = *it; //この行で、一行上の記述と同じことをさせたい

この場合はどうすればいいのでしょうか?
どうせポインタだから、って参照をそのまま代入したらエラーになったし、
勇気を出してキャストしてみてもエラーになりました。

よろしくお願いいたします。
810デフォルトの名無しさん:2007/12/18(火) 10:16:08
it = vec.begin() + 12; とか、
it = vec.begin();
std::advance(it,12);とか。
811デフォルトの名無しさん:2007/12/18(火) 10:22:33
ありがとうございます。
大変助かりました。
812デフォルトの名無しさん:2007/12/18(火) 12:21:40
test
813デフォルトの名無しさん:2007/12/18(火) 16:03:21
たぶん過去ログに無かった・・・と思うんだけど
class Test1
{public:
int base;
Test1()
{
base = 0;
}
void Add(int n)
{
base += n;
}
};

void hoge()
{
vector<int> v;
Test1 test;
v.push_back(1);
v.push_back(2);
v.push_back(3);
for_each(v.begin(), v.end(), test.Add); // ここでエラー
printf("%d", test.base);
}
これ解決するにはやっぱりイテレータでループ回すしかないんでしょうか。
上記のTest1クラスはあくまで例なので実際には別のクラスですけど。
814デフォルトの名無しさん:2007/12/18(火) 16:06:58
>>813
Boostにはそういうことをするためのbindというライブラリがある
標準にはない
815814:2007/12/18(火) 16:10:33
俺は何をねぼけてるんだ
std::mem_funがあるじゃないか
816デフォルトの名無しさん:2007/12/18(火) 16:11:59
>>813
結果はtestに入らないよね?
Test1 result = for_each(〜略
817デフォルトの名無しさん:2007/12/18(火) 16:13:00
あ、ごめん、勘違い。
818813:2007/12/18(火) 16:19:23
mem_funあたりは真っ先に試してみてるんだけど、
for_each(v.begin(), v.end(), test.Add);

for_each(v.begin(), v.end(), mem_fun(&Test1::Add)(&test));
これでもやっぱりだめなんですよね。
819デフォルトの名無しさん:2007/12/18(火) 16:30:07
for_each(v.begin(), v.end(), std::bind1st(std::mem_fun(&Test1::Add), &test));
これでできた
820813:2007/12/18(火) 16:33:54
>>819
ありがとう。ちなみにboost使ってもいいんだけど、それならもっと簡略化できますかね?
821デフォルトの名無しさん:2007/12/18(火) 16:36:42
for_each(v.begin(), v.end(), boost::bind(&Test1::Add, test, _1));
822813:2007/12/18(火) 16:41:10
それでいけそうです。どうもありがとう。
823デフォルトの名無しさん:2007/12/18(火) 19:22:33
testはboost::ref(test)にしないとだめじゃねーか?
824デフォルトの名無しさん:2007/12/18(火) 21:21:04
むしろポインタ渡しじゃね?
for_each(v.begin(), v.end(), boost::bind(&Test1::Add, &test, _1));
825デフォルトの名無しさん:2007/12/18(火) 22:10:22
C++初心者だけど
Effective C++買ってみた。
826デフォルトの名無しさん:2007/12/19(水) 02:37:04
で?
827デフォルトの名無しさん:2007/12/19(水) 02:58:23
いま俺の横で気持ちよさそうに寝てる
828デフォルトの名無しさん:2007/12/19(水) 03:53:08
あべさんが?
829デフォルトの名無しさん:2007/12/19(水) 21:02:38
>>824 で bind の第二引数を &test にしたら
自動的に参照渡し,test にしたら自動的に
値渡しになるの?

boost::bind すげぇ〜

んで,boost::lambda とどちら使えばいいんだ?
教えて!
830デフォルトの名無しさん:2007/12/19(水) 21:52:36
>>829
boost::lambda::bind
831デフォルトの名無しさん:2007/12/19(水) 22:13:27
>>830
_1 とかが両方にあって混乱する.
832デフォルトの名無しさん:2007/12/19(水) 22:35:25
class Test
{
  private:
    typedef boost::function<int, int> Functor;
    Functor calc;
    int num;
  public:
    Test(const string& str) : num(1)
    {
      map<string, Functor> funcs;
      funcs["plus"] = boost::bind(&Test::plus, this, _1);
      funcs["multiply"] = boost::bind(&Test::multiply, this, _1);
      this->calc = funcs[str];
    }
    int operator()(int n) { return this->calc(n); }
  private:
    int plus(int n) { return this->num + n; }
    int multiply(int n) { return this->num * n; }
};

こういうのって有り?
833デフォルトの名無しさん:2007/12/19(水) 22:43:45
funcsをコンストラクタで使い捨てにするんだったら、抵抗感あるな。
俺なら普通にifで切り分けていく。
あるいはそのmapを静的に持つ。
834デフォルトの名無しさん:2007/12/19(水) 23:00:03
>>832
悪い設計の見本みたいな例ではあるね
835デフォルトの名無しさん:2007/12/20(木) 00:58:42
LL言語なら普通にやるパターンだが。
パフォーマンスで問題が表面化しなければそれでいいんじゃないかね。
意図通りに動くのであれば。
836デフォルトの名無しさん:2007/12/20(木) 01:08:29
比較しなければならない文字列が数千とかある場合だったら、このやりかたは結構うまいと思うのだがどうよ。
数千の文字列と入力文字列を比較するうまいやりかたって標準C++にあるっけ。

よさげなアルゴリズム(←ヘッダ名ではなく一般名詞)でもいいけど、参考までに教えて。
837デフォルトの名無しさん:2007/12/20(木) 01:12:26
完全ハッシュ関数とか?
838デフォルトの名無しさん:2007/12/20(木) 01:51:11
>>837
完全ハッシュの計算はgperfとかで事前にやっとくとしても、与えられた文字列ハッシュするのって時間かかるんでない?
もっと速い方法無いかな。

839832:2007/12/20(木) 01:51:49
素直にifでやったほうが無難か。
ちなみに、コンストラクタ呼び出しはプロセス開始直後に数十回程度で、
作ったインスタンスはプロセス終了まで使い回すつもり。
840デフォルトの名無しさん:2007/12/20(木) 09:39:21
>>836
>>832の書き方だと、設定時に常に lower_bound が走る上にメモリ確保の回数も多くなるから、
無駄だと思うんだよね。if にくらべてどれだけ高速化するか微妙。

どうせなら、vector に、キーと値のペアを設定して、あらかじめ挿入するサイズを reserve してから
push_back でどんどん追加していき、1回ソートしてから、lower_bound で検索したほうが高速化すると思う。
841デフォルトの名無しさん:2007/12/20(木) 10:56:17
>>836
使ったことないけどトライとかどうよ。

>>832はmapを使い捨てるから効率は期待できない。
ただ俺は>>835に同意。性能が問題にならないなら書き易い方法を選ぶべき。
842デフォルトの名無しさん:2007/12/20(木) 12:14:20
map 作るのも vector をソートするのもキーの数 N に対して O(NlogN) になるよね?
だったら O(N) でも素直にループで比較するほうがマシなんじゃないの?

map やソート済み vector を全部のインスタンスで使いまわすようにすれば、
素直なループより効率よくなりそうではある。
843デフォルトの名無しさん:2007/12/20(木) 12:59:51
BOOL CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM , Boy *boy);
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
LPSTR lpsCmdLine, int nCmdShow)
{
DialogBox(hCurInst, "DLGBOX", NULL, (DLGPROC)DlgProc);
return 0;
}
BOOL CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam , Boy *boy)
{
char boy[256],ookisa[128],namae[128];
switch (msg )
{
case WM_INITDIALOG: //ダイアログボックスの初期化
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK://OKボタンが押されたら

GetDlgItemText(hDlg, IDC_FAIL1, namae, (int)sizeof(namae));
GetDlgItemText(hDlg, IDC_FAIL2, ookisa, (int)sizeof(ookisa));

wsprintf(boy, "名前を%sに、大きさを%sに変更しました", namae, ookisa);
MessageBox(hDlg, boys, "変更したぷぃ(>o<)b", MB_OK);
strcpy(boy->name,namae);           
boy->value[64] = ookisa[64];         
EndDialog(hDlg, IDOK);
return TRUE;
}
return FALSE;
}
return FALSE;
}
844デフォルトの名無しさん:2007/12/20(木) 13:02:25
上記プログラムでダイアログを作り、文字入力を行い、入力された文字を他の文字に代入したいと考えておりますが、上手く出来ません。何か方法はございませんが?

一応コンパイルまでは出来るんですが、ダイアログボックスに文字、数字を入力し、OKをクリックするとアプリケーションエラーになってしまいます。

どなたか教えていただけないでしょうか?
845デフォルトの名無しさん:2007/12/20(木) 13:31:08
>834-844
スレ違い。↓ここがいいかな?
Win32API質問箱 Build60
http://pc11.2ch.net/test/read.cgi/tech/1196874830/
846845:2007/12/20(木) 13:31:43
うあアンカーミスった。 >843-844 ね。
847デフォルトの名無しさん:2007/12/20(木) 14:30:43
>>842
「素直にループで比較」の計算量の検討が抜けてない?

>>841
トライ(trie)って、map<string>のred-black treeと比べて
どういう利点があるの?いまいちわからん。この例限定で
いいから教えて。
848デフォルトの名無しさん:2007/12/20(木) 14:34:56
>>847
単に連想配列として使う場合は、赤黒木の様に平衡を保つ並べ替え処理が行われないので速い。
849デフォルトの名無しさん:2007/12/20(木) 14:37:31
>>848
じゃぁ、
"aaa......aaa0001"
"aaa......aaa0002"
..
"aaa......aaa9999"
みたいなデータをつっこむとtrieだと遅くなるのかな。



850デフォルトの名無しさん:2007/12/20(木) 15:06:59
>>849
それだと赤黒木でも相当遅くなりそうだ。
文字列比較のたびに毎回大量のaを比べないといけないからな。
851デフォルトの名無しさん:2007/12/20(木) 15:38:08
ならhash (std::tr::unorderd_map?) かな。でも長い文字列のhashはそれはそれで遅いよな。
うーん。
852デフォルトの名無しさん:2007/12/20(木) 16:02:43
計ってみた。trieの実装はでっちあげなので余り真に受けないように。
先頭にP文字の'a'があって、それにQ文字のランダム(R種類から選ぶ)な文字が続く文字列を
N個つっこんで、10万回検索した。挿入の時間は計ってない。

trie: 4 map: 14 0 10 5000 256
trie: 29 map: 17 0 50 5000 256
trie: 8 map: 25 40 10 5000 256
trie: 2 map: 9 0 10 5000 32
trie: 10 map: 13 0 50 5000 32
trie: 9 map: 18 40 10 5000 32

左から、trieでの時間、mapでの時間、P、Q、N、R。
上から二番目、完全ランダムな50文字の場合を除けばtrieが速いな。
ただし上から二番目ではtrieが相当メモリを使ってて、N=10000では動かせなかった。
853デフォルトの名無しさん:2007/12/20(木) 19:17:30
>>849
いや、それはtrieの方が速いだろ
854デフォルトの名無しさん:2007/12/20(木) 20:59:16
>>853
えーと、なんでだ?
855デフォルトの名無しさん:2007/12/20(木) 23:52:10
>>852
挿入の時間も知りたい。平均m文字程度の大量の文字列を高速にソートしたいんだよね。
std::mapに突っ込んでiteratorが速いならそうするし、他の方法があるなら知りたい。
trieとかいうのも興味ある

単にvector<string> s;をsort(s.begin(),s.end())のほうが速かったりする?
それとも何か特殊なデータ構造が適当なのかな
856デフォルトの名無しさん:2007/12/21(金) 00:02:52
ソート目的ならバランスしてる必要はほぼゼロなんだから、
一般的なstd::mapを使うのは自明な方法の中では最悪だと思うけど・・・
857デフォルトの名無しさん:2007/12/21(金) 00:15:30
バランスしてないと最悪O(N2)でしょ
858デフォルトの名無しさん:2007/12/21(金) 05:59:50
STL勉強中で、基本的な質問なんだけど

string& func()
{
std::string s = "text";
return s;
}
という書き方は正しい?(stringじゃ無くてVectorなんかも同じ?)
859858:2007/12/21(金) 06:25:32
あれ、VSで動かすとwarning出るんだな。
とにかくfunc()内で動的に生成したstringオブジェクトを返すのは
どうすればいい?
普通にnew?
それだと解放はいつすべき?
860デフォルトの名無しさん:2007/12/21(金) 06:28:36
普通にnew
861858:2007/12/21(金) 07:12:38
>>860
どーも。で、解放は何時してやればいい?し忘れても問題ない?

あと、こんなのも駄目なの?

string instr = "text";
string outstr;
copy(instr.begin(), instr.end(), outstr.begin());
862デフォルトの名無しさん:2007/12/21(金) 07:43:04
>>858
局所変数の参照を返してはいけないのは普通の変数でも
STL系でもすべて同じ。
そのまま実体を返して不都合がなければ string 返しな。

>>861
試してないから間違ってるかもしれんが
copy(instr.begin(), instr.end(), insert_iterator( outstr ) );
だとおも。もしくは先に outstr.resize( instr.length() ); とか。
863858:2007/12/21(金) 08:46:12
>>862
レスさんくす

VSの混合モードで見ると>>858はstringのコンストラクター2回、
デストラクターが1回よばれてる。warningは出るけど、実は問題ないんじゃない?
とか思ったり。


>>861に関してはoutstrをstringの代わりにstringstream使えばいいみたいだけど、
(insert_iteratorはstringに使えない?)
シンプルな>>861のパターンが駄目ってのは美しくないよな。
864デフォルトの名無しさん:2007/12/21(金) 09:05:08
>>863
問題ある。たまたま動いてるだけだ。

copy使うなら、
copy(instr.begin(), instr.end(), back_inserter(outstr));
だな。
865858:2007/12/21(金) 09:16:26
>>864
どーも。back_inserterでいけたけど、上のiteratorやbegin()と何が違うんだよ。
866デフォルトの名無しさん:2007/12/21(金) 09:20:05
std::map の erase メソッドって,イテレータではなくて
キーを指定して削除する erase(key) のような呼び出しもできますよね?

このときマップに key が登録されていない場合には
例外が出るのですか?out_of_range が投げられるのかなぁ
とおもってずっと catch して待っているのですが,
いまだになんの音沙汰もありません.
867866:2007/12/21(金) 09:23:46
SGIのドキュメント見たら

size_type
erase(const key_type& x);
Deletes the element with the key value x from the map,
if one exists. Returns 1 if x existed in the map, 0 otherwise.

でした.どう見ても戻り値です.
本当にありがとうございました.
868デフォルトの名無しさん:2007/12/21(金) 09:29:29
>>865
insert_iteratorはテンプレート名であって関数名じゃないから、そのまま呼び出すのには使えない。
outstr.begin()を使うと、outstrの要素を上書きしながらコピーという意味になる。
outstrは空なので、上書きしようとしたら未定義動作が起こる。
back_inserter(outstr)なら、「outstrの末尾に追加」だから問題ない。
869858:2007/12/21(金) 10:47:42
>>868
上書きと末尾に追加を分ける必要があるのかなんだよなー
書き込む対象がstringなんだから、自動で増やしてくれてもいいと思うんだけど。

まぁ仕様の話しても仕方ないのでこのへんで。
870デフォルトの名無しさん:2007/12/21(金) 10:55:47
>>865
std::copy は *(oitr++) = *(iitr++); を繰りかえしてる。

イテレータを *( itr++ ) = ?; として使った場合に
begin() で得られるイテレータはこんな動作。

*(ptr++) = ?;

back_inserter で得られるイテレータはこんな動作(等価になる)。

container.push_back( ? );
871デフォルトの名無しさん:2007/12/21(金) 11:39:35
>>869
もうちょっと勉強すれば、なんでそうなっているのかとか、
自分がどれだけ不自然なことを要求してるのがわかると思うよ。
872858:2007/12/21(金) 11:49:14
>>870
memcpy同様の動作ってこと?
でも本来はストリームとして動作することが期待されるわけで、
内部の実装はどうであれ、取得したイテレーターはシーケンシャルな
アクセスが可能でないと困る。
人間的にはこっちのほうが自然だよ。
873デフォルトの名無しさん:2007/12/21(金) 12:14:31
領域が勝手に拡張される方が困ると思うけど
無限長のsequenceというconceptを新たに作れと?
874デフォルトの名無しさん:2007/12/21(金) 12:23:06
>>858というか、>>861が何をしたいのかさっぱり分からん。
outstr.assign(instr.begin(), instr.end())ってこと?
それともinsert?
875デフォルトの名無しさん:2007/12/21(金) 12:26:36
>>873
「人間的」とか宗教みたいなこと言い出したから、もうこれ以上話が深くはならんだろう。
876デフォルトの名無しさん:2007/12/21(金) 12:29:25
858にはC,C++は向いていないと思う。
877デフォルトの名無しさん:2007/12/21(金) 12:47:12
>>872
> でも本来はストリームとして動作することが期待されるわけで、

そのために stringstream なんてものがあるわけだが…

何を期待してるか知らんが string はそもそも char* のラッピングだぜ?
878858:2007/12/21(金) 13:14:01
いや、ずっとスクリプト系いじってたから
どうしてもSTLみたいなのに高度な抽象化を求めてしまうのよ。

>>873
stringって勝手に拡張されないの?

>>874
練習用なので意味は無い。

>>877
stringが固定長で変化しないっていう仕様なら文句は言っていない。
879デフォルトの名無しさん:2007/12/21(金) 13:22:08
stringが自動で拡張されることはない。だから
string s("foo");
s[4] = 'a';
とかやったら未定義。
operator[]で範囲チェックすらしないほど効率重視の設計だから、
イテレータへの書き込みで自動伸長しないのも自然だと思う。
880デフォルトの名無しさん:2007/12/21(金) 13:30:55
>>858
string func()
{
std::string s = "text";
return s;
}
881デフォルトの名無しさん:2007/12/21(金) 13:34:17
なんだ。スレが伸びてると思って期待したのに
またC++が難しくてスクリプトに逃げた奴が叩いてただけか。
世間ではもう冬休みかぁ…
882858:2007/12/21(金) 13:51:39
>>879
じゃぁ
str = "abc"  (abcやdefは実際はもっと長い文字列とする)
str += "def"
の場合は内部で再アロケーションするんじゃないの?
883デフォルトの名無しさん:2007/12/21(金) 13:58:56
>>882
そうだよ
884デフォルトの名無しさん:2007/12/21(金) 14:13:44
858は文字列が何なのか分かってないに一票。
885デフォルトの名無しさん:2007/12/21(金) 14:17:56
>>882
879は「 operator[] () では拡張されない」ということを書きたかったんじゃないかな。
いまその辺が話題なわけだから。拡張するしかないときには、当然拡張されるよ。

vector や string の operator[] に例えばレンジチェックが入ったら、
使える場面が大分限定されちゃうよね。
「範囲を超えるかもしれないのでチェックしてほしい」というレアな使い方以外では
ポインタやただの配列より強烈に遅いだけでメリット無いんだから。
886デフォルトの名無しさん:2007/12/21(金) 14:29:20
範囲のチェックしたければ at を使えばいい.
って,そういう話じゃないの?
887デフォルトの名無しさん:2007/12/21(金) 14:32:01
std::string::begin()の返すiteratorはrandom access iteratorではあるけども
back insert iteratorでないから
一方std::backinserter(Container)はback insert iteratorを返すのでok
888858:2007/12/21(金) 14:37:35
結局は内部的に
ptr++してる時([]も含む)はレンジチェックは一切行われず、
意図的にデータを追加する処理を呼び出したときのみレンジチェックがされて
足りなければ追加されるってことでいいのかな?

で、copy動作は追加では無く単にptr++動作でしかないために
動的に拡張されず、したがって>>861みたいな書き方が出来ないと。

でもiteratorに対して読み込みは出来るが書き込みは出来ないって言う
非対称性はどうも綺麗じゃないと思うな。まぁ思うだけにしておくけど。
889デフォルトの名無しさん:2007/12/21(金) 14:38:28
back_insert_iteratorはコンセプトじゃねーぞ
890デフォルトの名無しさん:2007/12/21(金) 14:40:33
>>878
抽象化もなにも、抽象化されたcopyというアルゴリズムの意味をおまえさんが理解していなかった(しようとしない)だけだろ。

C++の<algorithm>ではコピーの本質は>>870に書いてあるとおり純粋な情報の移動の
ことで、メモリ割り当てはまた別の話とされている。
どこからコピーするか、どこへコピーするかはイテレータによって抽象化されている。
ストリームとしての動作が当然なんて言う狭い考え方の基には作られていない。

そういう動作が欲しければ、別途そういうライブラリを作るなり調達するなり、
委員会に提案するなりすればいいんじゃないか。copy_back_insertとか(笑)
891デフォルトの名無しさん:2007/12/21(金) 14:40:48
書き込みできるよ。

std::string in("abc");
std::string buf("uvxyz");
std::copy(in.begin(), in.end(), buf.begin());
/* bufは"abcyz"になる */
892デフォルトの名無しさん:2007/12/21(金) 14:41:07
じゃback insert iteratorがさすものはback insertion sequenceだから
893デフォルトの名無しさん:2007/12/21(金) 14:42:56
>>888
> 意図的にデータを追加する処理を呼び出したときのみレンジチェックがされて
> 足りなければ追加されるってことでいいのかな?
いや、back_inserter は末尾に追加するだけ。
レンジチェックもクソもない。「末尾に追加」する。

> で、copy動作は追加では無く単にptr++動作でしかないために
> 動的に拡張されず、したがって>>861みたいな書き方が出来ないと。
yes。同様の罠が transform とかにもあるから注意。

> でもiteratorに対して読み込みは出来るが書き込みは出来ないって言う
> 非対称性はどうも綺麗じゃないと思うな。まぁ思うだけにしておくけど。
ダウト。書き込みは上書き扱い。
配列でポインタ使ったときとちょうど対称になるでしょ?
他の言語との対象性は知らんがw
894858:2007/12/21(金) 14:43:34
微妙に不正確
copy動作は>>861のようなコピー動作に限っての話
895デフォルトの名無しさん:2007/12/21(金) 14:46:01
string& func()
{
:string *s = new string ;
*s="text";
return s;
}
でいいんじゃないの
896858:2007/12/21(金) 14:51:39
>>890
抽象化という言葉の捕らえ方が俺とは逆だね。
ストリームからストリームへデータを移動させる、ってのが抽象的な表現で
イテレーターがどのような挙動をするかは実装依存。
俺はその実装がどうなっているかわかってないから困ってるのだ。

>>893
いつレンジチェックされるんだろうw
.netのmarshal系なんて>>861の書き方に近かったと思うけど。

いやまぁいろいろ勉強になったよ。
897デフォルトの名無しさん:2007/12/21(金) 14:52:24
STLPortのリファレンスではstd::basic_stringは
back insertion sequenceじゃないのでback_inserterの引数にできないはずなんだけど
ISO/IEC 14882:2003ではback_inserter(Container)になってる
どっちを信用すればいいんだ・・・ってそりゃ規格の方か
もしかしてこのリファレンスって信用ならんしろものなの?
898デフォルトの名無しさん:2007/12/21(金) 14:53:25
string& func()
{
string *s = new string ;
*s="hoge";
return *s;
}
899858:2007/12/21(金) 14:54:02
>>895
呼び出し元はfunc()がどのようにstringを確保したか知らない前提とした場合、
deleteは誰がする?
900デフォルトの名無しさん:2007/12/21(金) 14:56:17
>>895
delete しないでいい処理なんかでは使えるかもね。
901デフォルトの名無しさん:2007/12/21(金) 15:01:24
なんか言葉が噛み合ってないな。

>>896
str.begin()で取ったイテレータもちゃんとストリームになってる。
このストリームにデータを流し込むのはstrの要素を上書きするのと同じ。
だから、このストリームには流せるデータ数に制限がある。

で、back_inserter(str)で取ったイテレータはこれとは別のストリームで、
これにデータを流し込むのはstrに要素を追加するのと同じ。よって無制限に流せる。

これで一貫してると思わないか?
902デフォルトの名無しさん:2007/12/21(金) 15:04:24
C++においてストリームって言葉はどう定義されているんだっけ?
903デフォルトの名無しさん:2007/12/21(金) 15:04:56
「抽象」やストリームもbuzzwordだったんだね
904デフォルトの名無しさん:2007/12/21(金) 15:05:52
C++でストリームというのはbasic_istreamやbasic_ostreamを継承したクラスのことだから
別の意味で使わない方がいいよ。
905デフォルトの名無しさん:2007/12/21(金) 15:07:09
「抽象」は皆同じ意味で使ってるだろ。
906デフォルトの名無しさん:2007/12/21(金) 15:13:30
main(){
string a;
a.reserve(70000000);
string().swap(a);
int n;scanf("%d",&n);
}

で解放できるけど、newと参照の場合は解放できない 消し方は無いのかも
907デフォルトの名無しさん:2007/12/21(金) 15:14:21
s/ストリーム/Sequence
でもいまのところ意味は同じにみえる
908デフォルトの名無しさん:2007/12/21(金) 15:18:27
こっちは解放するけど、

main(){
string a;
a.resize(100000000);
cout<<a.size();
string().swap(a);
int n;scanf("%d",&n);
}

こっちは解放しない

string& func(){
string *s = new string;
(*s).resize(100000000);
return *s;}

main(){
string a=func();
cout<<a.size();
string().swap(a);
int n;scanf("%d",&n);
}
909858:2007/12/21(金) 15:21:05
>>901
大丈夫だよw
ただ、別のストリームが登場してくるのがいやだっただけ。

一貫性なら単一のイテレーターでいろいろ出来るほうが楽だと思うが、
実装がパフォーマンスとの兼ね合いでそうなっているならまぁ仕方が無いのかと。


>>904
俺は単に流し込むものくらいの意味で使ってた。
910デフォルトの名無しさん:2007/12/21(金) 15:21:13
これでも無理

string& func(){
string *s = new string;
(*s).resize(100000000);
return *s;}

main(){
string a;
a=func();
string().swap(a);
delete(&a);
int n; scanf("%d",&n);
}
911デフォルトの名無しさん:2007/12/21(金) 15:29:00
もとのアドレスがわからなくなるのにちゃんと使えている

string& func(){
string *s = new string;
cout<<"s="<<s<<endl;
(*s).resize(100000000);
*s="hoge";
return *s;}

main(){
string a;
cout<<"a="<<&a<<endl;
a=func();
cout<<"a="<<&a<<endl;
cout<<a<<endl;
int n; scanf("%d",&n);
}
912デフォルトの名無しさん:2007/12/21(金) 15:33:13
これでOKだった

string& func(){
string *s = new string;
(*s).resize(100000000);
return *s;}

main(){
string *a;
a=&func();
string().swap(*a);
int n; scanf("%d",&n);
}
913デフォルトの名無しさん:2007/12/21(金) 15:34:50
>>909
「光学センサー付き絶対安全金槌ただし一回振るのに10秒かかる」と「石」、
しかなかったら、釘を打つのには結局は石を使っちゃうでしょう。
だったら普通の金槌を用意するのが妥当、と。
914デフォルトの名無しさん:2007/12/21(金) 15:37:04
>int n; scanf("%d",&n);
これってもしかしたらGUI環境用のおまじない?
だったらgetchar()だけで済むだろうに……

つーか、なんか思いっきり勘違いしている気がする。
複数レスに跨っているから指摘するのは面倒だから遠慮するけど。
915デフォルトの名無しさん:2007/12/21(金) 17:12:54
stringがリークしてるし、こんな糞コード実際に使われたらかなわん
916C++脳:2007/12/21(金) 17:34:40
GC脳とC脳
ってコワいですね。
917デフォルトの名無しさん:2007/12/21(金) 18:28:27
>>915
まったくだ、だれがDeleteしてるんだっていうね
918デフォルトの名無しさん:2007/12/21(金) 19:28:55
なんでせめて auto_ptr にしないのん?
919デフォルトの名無しさん:2007/12/21(金) 19:35:53
auto_ptrで解放したら、だめだろう
920デフォルトの名無しさん:2007/12/21(金) 21:02:03
はいはいstd::tr1::shared_ptr
921デフォルトの名無しさん:2007/12/21(金) 22:12:45
【今後の流れ】
「規則でtr1使えません><」
「自分で作れカス」
922デフォルトの名無しさん:2007/12/21(金) 22:28:52
namespace std {
    using tr1::shared_ptr;
}
923デフォルトの名無しさん:2007/12/21(金) 22:30:25
Glib::RefPtrをですね、
924デフォルトの名無しさん:2007/12/22(土) 00:52:07
>>896
> 抽象化という言葉の捕らえ方が俺とは逆だね。

そういう問題ではないだろう。
何かを抽象化するときに、視点が違えば別の解になる。
STL は挙動で抽象化してるから、君の視点と違うせいで、おかしな設計に見えるのだろう。
STL の設計思想に慣れるしかない。
925デフォルトの名無しさん:2007/12/22(土) 21:54:31
むしろアクセスするだけで勝手に拡張されるほうが気持ち悪いと思う・・・
範囲外アクセスになったときは素直に落ちて欲しいなあ
926デフォルトの名無しさん:2007/12/23(日) 01:55:44
それなんてmap::operator[]

え?find使えって?
927858:2007/12/23(日) 09:52:22
>>924
抽象化に視点はあまり関係ないと思うぞ。
上での例を使うと、copyという操作は概念としてAからBへデータを複製することになる。
そして、copyという語自体、それ以上の意味を持っていない。

しかし、C/C++のmemcpyなどでは
・コピー元A、コピー先B共にメモリ上のデータであること。
・コピー先Bに必要な領域が確保されていること。
という条件が付く。(memcpyの仕様)

そして、上のほうで書いたcopy操作もmemcpyと同じ条件が付く(ので合ってるのか?)

これは抽象的概念を具現化する過程で(つまりは実装すること)
その実装方法によりいくつかの条件、制限が付加される。
視点が違うと感じられるのは、この実装過程での思想の違いによるものでしかない。
だから各条件に応じて数種類のイテレーターを使い分けなければいけなくなる。

抽象化というのは、このような条件、制限を出来るだけ撤廃してオリジナルの
概念をあらゆる場面で適用出来るようにすること。

たとえば、copy fileA, fileBを実装する場合、Bが自動的に拡張されないように
実装したら馬鹿だと言われるぞ。
928858:2007/12/23(日) 10:04:48
なので、条件、制限がある場合はそれが適切に分かるような関数名にすべきだと思う。

シンプルな関数名はシンプルな動作が期待されるわけで、その関数がどのような実装で
あるのか知る必要もないくらい、あらゆる場面で使用できるってのが理想的。
929デフォルトの名無しさん:2007/12/23(日) 10:12:18
>>927
>そして、上のほうで書いたcopy操作もmemcpyと同じ条件が付く(ので合ってるのか?)
合ってない。例えば標準入力を標準出力にコピーする操作もcopyで書けるけど、
この操作はどちらの条件も満たしていない。

自動的に拡張されないのはstringの仕様(もっといえばstring::beginの仕様)であって、
copyはそんなことには関知しない。
930デフォルトの名無しさん:2007/12/23(日) 10:14:16
string::beginの仕様じゃなくてstring::iteratorの仕様と言った方が適切だな、すまん。
931デフォルトの名無しさん:2007/12/23(日) 10:35:14
>>927
> 抽象化に視点はあまり関係ないと思うぞ。
設計によってインターフェースが違ったりするよね?
それを、抽象化の視点が違うから、と説明するのはおかしいと思う?

例えば GUI の実装がいくつもあって互いにかけ離れたものがあるけど、同じように抽象化したのにインターフェースが別物になったと思う?
なら、抽象化という単語の意味を取り違えていると思うよ。

俺は、挙動を iterator で分類する抽象化はなかなかいいと思うけどね。
932デフォルトの名無しさん:2007/12/23(日) 11:40:38
> 上での例を使うと、copyという操作は概念としてAからBへデータを複製することになる。
> そして、copyという語自体、それ以上の意味を持っていない。

わかってんじゃん。
それなのになぜ、

> そして、上のほうで書いたcopy操作もmemcpyと同じ条件が付く(ので合ってるのか?)

なんてトンチンカンなことが出てくるのかがわからん。
そんな条件は無いし、ましてやコピー先が自動的伸縮できることという条件も無い。
そんな制限があったら使えるシチュエーションが限られてしまうじゃないか。

それは実装の詳細だから包み隠されているべきと言うだろうが、
それはあるレイヤーの上にいる人の視点。
その実装の中にも設計があることをお忘れ無く。
伸縮するバッファを実装する人がcopyを使えなくなってしまうでしょ。
933デフォルトの名無しさん:2007/12/23(日) 11:53:53
stl:set って挿入するときに「同じ値」だと挿入されないですよね?
その「同じ値」って言うのは operator < だけで判定してるんですか?
それとも別途 operator == が定義されていなくてはだめですか?
934デフォルトの名無しさん:2007/12/23(日) 12:10:37
<だけ。
935デフォルトの名無しさん:2007/12/23(日) 12:45:14
iteratorの中の人
936デフォルトの名無しさん:2007/12/23(日) 12:54:57
>>933
!( a < b ) && !( b < a ) なら a == b
937858:2007/12/23(日) 12:59:50
>>931
言っていることがよくわからん。
プログラム的な抽象化ってのは、一度細分化された後で
同様の概念を持つものを再統合するようなイメージ。

インターフェイスの違いなどはまだ細分化されたままの次元において出てくる話。
なのでそういう部分を指して話をするのであれば、抽象化の話とは違うと思う。


>>932
本当にcopyに関しては何も条件は無い?
イテレーターの正体がメモリのポインターであっても、ファイルポインターであっても
STLのコンテナであっても?
そして全て同様の動作が期待されると考えてよいの?
>>870は間違い?それともイテレーター次第?イテレーターに依存するのであれば、
それも条件のうちだよ。

>それはあるレイヤーの上にいる人の視点。
逆に言えばC++の人はそういう細かい実装中心で思考してるわけで、
そもそも俺が言っている条件のようなものは空気のようなもので
普段は意識してないのかもしれない。
938デフォルトの名無しさん:2007/12/23(日) 13:03:22
自然言語上での抽象化なんて誤解の元でしかないということだけはわかった
939858:2007/12/23(日) 13:12:20
そうそう、結局知りたかったのは、ライブラリがどのように実装されているかを
知っているということがSTL(boostも)を使いこなす前提となっているのかどうかってこと。

知らないよりは知っているほうがいいだろうが、実装を知らないまま使うことが
不可能に近いレベルで無理なのか?というところを知りたい。
940デフォルトの名無しさん:2007/12/23(日) 13:16:19
実装は知らなくてもいいけどconceptを知らないとtemplateを使えない
941デフォルトの名無しさん:2007/12/23(日) 13:32:38
実装を知らないと何に使うのかわからない、というようなことはあるかもな。
dequeとか。
942デフォルトの名無しさん:2007/12/23(日) 13:40:41
c++初心者用で聞けば良いのか迷いましたがSTLを使っているためこちらで質問させていただきます。

あるクラスPointがあり
コンストラクタは2つの引数を受け取るものです。Point(int x,int y){・・・}
vectorを使用してPointクラスのポインタのリストを作成したいのですが
どのようにすればよいのでしょうか?よろしくおねがいします。


以下 厳しい突っ込み覚悟のメモ書き
vector<Point *> test;
↑もし このような形であっているとしたら、その後、値を入れるにはどうすればよいのでしょうか?

test@push_back(@);
↑一応このような形かも とは考えて見ましたが(@はどうすればいいのか検討もつきませんorz) 

943デフォルトの名無しさん:2007/12/23(日) 13:48:08
>>937
copyが内部で
*iter++ = ???;
みたいな操作をやってるってのは実装の詳細でもなんでもなくて、copyのインタフェースの一部だ。
そもそも出力イテレータというのは、*iter = ???の代入が意味を持つ型のこと(もうちょっと制限があるけど)で、
copyというのはこの操作を入力イテレータが指す範囲のそれぞれの要素について行うものと定義されている。

ただし、copyの内部が
*iter++ = ???;
なのか
*iter = ???;
iter++;
なのか
*iter = ???;
++iter;
なのかは本当に実装の詳細だけどな。
944デフォルトの名無しさん:2007/12/23(日) 13:48:27
test.push_back(new Point(0, 0));
945デフォルトの名無しさん:2007/12/23(日) 13:50:19
>>943
後置++はありえんだろ。効率的に。
946デフォルトの名無しさん:2007/12/23(日) 13:56:22
>>945
今はcopyの実装が実際にどうなってるかを問題にしてるわけじゃなくて、
copyの実装をどこまで知っている必要があるかの話をしている。
たとえ後置++を使ったcopyの実装があったとしても、正しい出力イテレータを与えれば
前置++を使ったcopyの実装と同じ挙動を示すというのが重要。
947858:2007/12/23(日) 14:09:24
>>943
いや、そうでなくて。
少なくとも*iter++と書くこと自体、メモリ上のポインターであることを前提としている。

イテレーターがファイルのポインターだとすると
概念的には
file[filepos++] = ???
のように表せるはず。
(内部の実装では当然メモリ上のコピー動作は発生するが、
その後ファイルへの書き込みまで行って操作が完結するので
実装を全く意識せずに表すとこうなる)

だから、本当にメモリのポインター操作しか行わないのか
上記のような高度な操作もしているのかどうかということ。

もし、メモリ上のポインターのみであれば、それは実装を意識していることになるんだけど。
948デフォルトの名無しさん:2007/12/23(日) 14:19:26
>>947
>少なくとも*iter++と書くこと自体、メモリ上のポインターであることを前提としている。
してないよ。
この式には二つの演算子(後置++と前置*)が出て来るけど、どっちもオーバーロードできる。
ファイルへの書き込みを行うイテレータなら、
*iter++ = ???;
と書いたときに、内部的に
file[filepos++] = ???;
を行うようなオーバーロードを行なっている。
949デフォルトの名無しさん:2007/12/23(日) 14:20:00
とりあえず俺は中身を知った上で毎回同じことを書く手間と
それに付随するニアミスを防ぐためにライブラリを使うものだと思ってる。

中身を知る労力すら惜しい輩は一生 ruby でも書きなぐってればいいのに。
950デフォルトの名無しさん:2007/12/23(日) 14:22:13
そこはJavaと言っとくべきじゃないか、C++的には。
951デフォルトの名無しさん:2007/12/23(日) 14:26:29
>>949
別に知らなくても使えるんだから、そうやって使いたい奴が使うのを止める理由はないじゃん。
952デフォルトの名無しさん:2007/12/23(日) 14:26:51
*iter++ができるということはinput iteratorとしての用件をみたす
ちなみにpointerはrandom access iteratorとしての用件をみたす
953デフォルトの名無しさん:2007/12/23(日) 14:28:03
要件
954858:2007/12/23(日) 14:30:16
抽象化がちゃんと機能していれば特定機能を持つキーワードを繋げていけば
どのようなオブジェクトでも処理ができるので、その方が物作り的効率はいいんだよね。

実はrubyで特定処理が遅いからC++化しようとしてるだけだったりするw
955デフォルトの名無しさん:2007/12/23(日) 14:33:40
>>954
>>948は無視か?

とりあえず>>858にC++を教えた奴(か書籍)は、
イテレータがそもそも++と*で成り立ってるってことを紹介するべきだな

# include <iterator>
# include <iostream>

int main(void)
{
  std::ostream_iterator<int> oi(std::cout, "\n");
  *oi++ = 1;
  *oi++ = 2;
  *oi++ = 3;
}
956858:2007/12/23(日) 14:33:43
実装知らずに使ってみて、何回も頭ぶつけるから仕方なくソース見てるってのがホントじゃない?
boostまで理解しようとしたら、みっちりやって半年か1年くらいかかりそうだ。
957デフォルトの名無しさん:2007/12/23(日) 14:36:33
そもそも string に stringstream の機能を求めるような人に
抽象化が機能してるとかしてないとか言えるのかと。
ただ知らない、分かってないだけじゃないかと。

まぁ、何でも混ぜるrubyの弊害なのは分かるんだけどさ…
初心者にとっては機能の単位が分かりづらくなるから
あんまり勉強には向かないんだよなぁ。
958デフォルトの名無しさん:2007/12/23(日) 14:37:56
>>956
プログラミングってそうやって習得するものじゃないの?
959858:2007/12/23(日) 14:39:13
>>955
見落としてたよw
ファイルの扱いに関しては理解した。
後はまた元に戻るけど、copyのようにイテレーター間のデータの移動についてはどう?
ファイルストリーム→string
vector→list
のようなコピーも定義されてるの?
960デフォルトの名無しさん:2007/12/23(日) 14:42:32
>>959
それも全部copyでできる。
追記か挿入か上書きかで出力イテレータを使い分けるのも同じ。
961858:2007/12/23(日) 14:47:04
>>960
なるほど、てことはイテレーターの使い分けが肝であり、
そのイテレーターが何故複数存在しているか理解すれば一番早いと理解してOK?
て言うかイテレーター含め型多すぎだよ。
962858:2007/12/23(日) 14:50:08
>>957
stringとstringstreamが独立して必要な理由を教えてもらえるとありがたい。
実装上の都合という理由以外で。
stringって変更不可なオブジェクトでは無かったと思うけど。
963デフォルトの名無しさん:2007/12/23(日) 15:00:18
というかなんか>>959は誤解してるっぽいな。
個々の対象(ファイルストリームとかvectorとかstringとか)のそれぞれに、
専用のcopyが定義されてるわけじゃないぞ。
copyの実装は一つで、ひたすら
*出力イテレータ++ = *入力イテレータ++;
のようなことを繰り返すだけのものとして定義されてる。
どこに書き込むか、どうやって書き込むか(追記か上書きか、とか)を知っているのはイテレータだけで、
それに応じて++と*をオーバーロードしている。

>>961
うん、それでいい。
あと、練習としてアルゴリズムを一つ書いてみたら良いと思う。
入力を一つおきに捨てながら出力にコピーするskip_copyとかどうだろうか。
で、それがファイルにもstringにもlistにも適用できることを確認する。
964858:2007/12/23(日) 15:10:39
>>963
ありがとう、感覚的にかなり分かってきたような気がするw
イテレーターが独立してクラス化されてる理由もなんとなくわかった。
965デフォルトの名無しさん:2007/12/23(日) 16:15:30
>>962
> stringとstringstreamが独立して必要な理由を教えてもらえるとありがたい。

両者が概念からして全く別のものだから。

というか、文字列を扱うということ以外に共通点が見つからないんだけど。
966965:2007/12/23(日) 16:19:12
補足。

string は文字列を”保持”して”扱う”ためのもの。

stringstream はクラス階層を見ても分かる通り、
そもそも「データを流し込むもの=stream」であって、
流し込む対象が文字列なだけ。
対象がファイルになると iostream になるし。
967デフォルトの名無しさん:2007/12/23(日) 16:45:09
std::back_insert_iteratorのvalue_typeやreferenceがvoidなのは何故ですか?
vc8ではreferenceはcontainer::referenceになってましたが
968858:2007/12/23(日) 16:53:40
>>966
うそ臭い説明だなw
じゃぁ単なるstringはストリームとしての特性を全く持っていないのか?
先頭から1文字ずつアクセスできるし、文字列の後ろに文字を追加することも出来る。
cout <<に対して出力も出来るし、stringのイテレーターからの>>も出来たんじゃなかった?
stringもストリームとしての要素は持っていることになると思うけど。

たとえば、stringオブジェクトは1度作ると変更できない、というような特性があるのなら
別のストリームオブジェクトが必要になるのは分かるが、そうでは無い。

だから、やはり単にstringstreamがstream系のオブジェクトを継承しているかどうかに
拠るというのが理由で、実装上の都合のように見えるのだけど。
969デフォルトの名無しさん:2007/12/23(日) 17:00:56
>>968
> じゃぁ単なるstringはストリームとしての特性を全く持っていないのか?
yes

> 先頭から1文字ずつアクセスできるし、文字列の後ろに文字を追加することも出来る。
配列も先頭から1文字ずつアクセスできるけどストリームか?
mrealloc で配列の後ろに追加できるけどポインタもストリームになるのか?

> cout <<に対して出力も出来るし、stringのイテレーターからの>>も出来たんじゃなかった?
int も cout に << できるけど int ってストリームか?

つまり、ストリームの理解が間違ってる。
970858:2007/12/23(日) 17:14:40
「データを流し込むもの=stream」
って言ったのはそっちだよw

その定義であれば、配列もintもストリームだし。(ストリーム化可能と言うべきか)
971デフォルトの名無しさん:2007/12/23(日) 17:19:12
>>970
> 「データを流し込むもの=stream」
> って言ったのはそっちだよw

どういう理解をすればああいうレスが出来るのか不思議…

cout << var1 << var2 << var3・・・
^^^^^
こういう風にデータを流し込むことができる対象ってことなんだけどなぁ。
972デフォルトの名無しさん:2007/12/23(日) 17:30:37
なんか不毛な揚げ足取りになってるな。
まずstringはコンテナだというデザインを受け入れないと何でもアリになるんじゃ?
973デフォルトの名無しさん:2007/12/23(日) 17:41:03
stream(流し込むもの)ってのは流し込めることが重要なんであって、
流し込む先がどうなるかについては言及していない。
stringの+=は「末尾に追加する」の意味であって、「流し込む」わけではない。
974858:2007/12/23(日) 17:47:27
>>971
あーすまん、流し込むもの→流し込む対象のものって意味なのか。
さすがに次スレまで引っ張るつもりは無いのでこのへんで。
975デフォルトの名無しさん:2007/12/23(日) 17:49:03
>>974
あー。「流し込む”もの”」ってことか。
なるほど。そういう誤解されるとは思いつかなかった。スマン。
976デフォルトの名無しさん:2007/12/23(日) 17:50:11
どう考えたらそう誤解になるのか不思議だ
cout, cinの使い方考えたらわかるだろうに
977858:2007/12/23(日) 18:08:11
いや、特性上どう違うのかっていう説明はもらってないし
極端な話、vectorクラスで<<をオーバーロードしちゃえば
vec << newobject
なんて書き方も可能だよ。違いはそういうところじゃないはず。
978デフォルトの名無しさん:2007/12/23(日) 18:30:51
ストリームもイテレータもプロトコルなんだよ。個々の事物で考えようとするからいけない。
979デフォルトの名無しさん:2007/12/23(日) 18:43:20
さて、もういい加減に次スレは要らないよね?
980デフォルトの名無しさん:2007/12/23(日) 18:45:58
5ヶ月も満たないうちに一スレ消費するほどのスレを存続させないとはこれ如何に?
981デフォルトの名無しさん:2007/12/23(日) 18:57:23
立ててくる
982デフォルトの名無しさん:2007/12/23(日) 19:01:35
無理だった
983デフォルトの名無しさん:2007/12/23(日) 19:24:06
>>980
C++相談室でやればいいってことだよ。
984デフォルトの名無しさん:2007/12/23(日) 19:35:18
C++でストリームと言ったら、std::basic_ios<>の派生クラス。
std::stringstreamは、std::basic_stringstream<char>のtypedefで、
basic_stringstream<>は、その基底クラスを辿っていくとbasic_ios<>に辿り着くのでストリームである。

つまり、
> だから、やはり単にstringstreamがstream系のオブジェクトを継承しているかどうかに
> 拠るというのが理由で、実装上の都合のように見えるのだけど
俺もこうだと思う。stringに、ストリームにする皮を被せたのがstringstream。
985デフォルトの名無しさん:2007/12/23(日) 19:36:58
俺は前みたいにC++テンプレート全般を扱うスレッドのほうがいいなと思っている。
986デフォルトの名無しさん:2007/12/23(日) 19:53:23
久しぶりに見てみたらなんだよ
このおバカ全開な流れは
987デフォルトの名無しさん:2007/12/23(日) 19:55:02
嫌なら黙って閉じればいい
988デフォルトの名無しさん:2007/12/23(日) 20:23:31
>>984
どうもその説明に違和感がある。
stringを包んでいるのはstringbufで、stringstreamはストリームバッファとして
stringbufを使っているだけにすぎん。
989デフォルトの名無しさん:2007/12/23(日) 20:27:37
>>988
同意。
HDD の代わりに string を使ってる iostream みたいなものだと認識してるが。
990984:2007/12/23(日) 20:40:15
988にも989にも同意なんだが、
つまり俺の説明がへたくそなだけだ。すまん
991デフォルトの名無しさん:2007/12/23(日) 21:32:25
map使ってDB作りました
992デフォルトの名無しさん:2007/12/23(日) 23:02:40
multimapを比較関数オブジェクトを使って
multimap<int,string,greater<int> >と宣言するとエラーが起きるのですが
なぜなんでしょうか?
なぜかtypedefするとコンパイラを通ります。
993デフォルトの名無しさん:2007/12/23(日) 23:08:12
typename な気がするが、"そんな初歩的なミスなわけねーだろ! 肉球ぷにぷにして悶え氏ね"ってんなら、環境とか処理系とかエラーメッセージとか書くべき。
994デフォルトの名無しさん:2007/12/23(日) 23:19:19
遅ればせながら>>944の方ありがとうございました。
995992:2007/12/23(日) 23:29:28
a.cpp: function 内の `int main(int, char**)':
a.cpp:41: error: no matching function for call to `std::multimap<int,
std::string, std::greater<int>, std::allocator<std::pair<const int,
std::string> > >::insert(int&, std::string&)'
C:/mingw-jp/include/c++/3.3.3/bits/stl_multimap.h:326: error: candidates are:
typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>,
std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::iterator
std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const
_Key, _Tp>&) [with _Key = int, _Tp = std::string, _Compare =
std::greater<int>, _Alloc = std::allocator<std::pair<const int, std::string>

>]
C:/mingw-jp/include/c++/3.3.3/bits/stl_multimap.h:350: error:
typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>,
std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::iterator
std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(typename
std::_Rb_tree<_Key, std::pair<const _Key, _Tp>,
std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, _Alloc>::iterator,
const std::pair<const _Key, _Tp>&) [with _Key = int, _Tp = std::string,
_Compare = std::greater<int>, _Alloc = std::allocator<std::pair<const int,
std::string> >]
996デフォルトの名無しさん:2007/12/23(日) 23:57:34
>>995
insertの呼び出しが間違ってるだけのように見えるが。
997デフォルトの名無しさん:2007/12/24(月) 03:14:47
お馬鹿全開かつ痛い流れのような気がして見てなかったけど、
もしかしたら見落としてる基本が掘り起こされてるかもしれないから、おさらいしておくことにする。

何も掘り起こされてなかったら、次スレで何も無かったようにROMる。
新たな発見があったら、、恥かしいからやっぱ何事も無かったかのようにROMる。

そして、酔っ払ってるから今日は寝る。
998858:2007/12/24(月) 03:45:15
次すれ立ててやったぞ

【C++】STL(Standard Template Library)相談室 8
http://pc11.2ch.net/test/read.cgi/tech/1198435319/
999デフォルトの名無しさん:2007/12/24(月) 03:56:48
てめぇでだいぶ消費したんだから当然だ












スレ立て乙
1000デフォルトの名無しさん:2007/12/24(月) 04:04:34
>>1000 メリークリスマス
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。