【C++】STL(Standard Template Library)相談室 3
2 :
デフォルトの名無しさん:2005/05/20(金) 12:28:48
VCのSTLはどこら辺が腐っているのですか?
9 :
デフォルトの名無しさん:2005/05/20(金) 13:11:51
汁との「STL標準講座」はVC6で動作確認してる。
俺もVC以外使わないから
事実上はVCが世界の標準なわけだし、
>>9 >事実上はVCが世界の標準なわけだし
>事実上はVCが世界の標準なわけだし
>事実上はVCが世界の標準なわけだし
バカが勃てたスレにバカが。
デフォルトアロケータが省略できないような糞STL=VC6はいらんとですよ。
14 :
デフォルトの名無しさん:2005/05/20(金) 15:51:16
事実上はマイクロソフトが世界の標準なわけだし
15 :
デフォルトの名無しさん:2005/05/20(金) 15:52:56
>>13 それ、99%おまえのコーディングミス。
C++の基礎事項をチェック。
VC6ならあるいはそういうことがあっても不思議ではなかろう
#pragma warning (disable : 4786)
↑↑糞なVC6だけに必要なプラグマですね(プ
このスレはなにげにレベルたかいな・・・
クオリティなら高いかもな
20 :
デフォルトの名無しさん:2005/05/20(金) 23:19:28
黒ジャーを作るテンプレートないですか
VCのhash_mapはO(N)じゃなくてO(logN)だって聞いたんで
速攻STLPortにしますた。
それじゃ逆効果だろw
>>21 正しくはO(N logN)ね、
愚かな人間のくせになまいきな・・
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++標準ライブラリだ。
範囲が明確に決まってるかのように、含まれるだの含まれないだの言うのは時代遅れだぞ。
このスレが不要である事に疑いの余地は無い。
>>24 テンプレートを使わないスタイルの人や
テンプレートの相談なんて必要無い人(vector,list,stringの一般的な使い方で十分な人)も
まだまだ多いからC++スレにテンプレート厨を入れたく無いってのが本当の理由だろうな。
いってみりゃただの隔離スレw
でも、必要でしょ?テンプレート厨ウザイからw
std::stringって文字列受け取ったときに内部のバッファにコピーするんでしたっけ?
int main(void)
{
string str;
//寿命の短いほげほげ
{
str = "HogeHoge";
}
//スコープ外れても大丈夫?
printf(str.c_str());
return 0;
}
>>27 >std::stringって文字列受け取ったときに内部のバッファにコピーするんでしたっけ?
する。
ちなみに、文字列リテラルはプログラムの実行中ずっと生きてる。
29 :
デフォルトの名無しさん:2005/05/25(水) 10:39:43
vector<int> v;
vector<int>::const_iterator p=v.begin();
こういう使い方をしていると、v の型を(たとえばlist<int>などに)変えたときに
「vector<int>::」の箇所も変えなくてはならなくて不便なので、
v.const_iterator p=v.begin();
という感じのことをしたいのですが、これだとコンパイルエラーになってしまいます。
このようなことをする方法ってありますか?
>>29 typedef vector<int> v_type;
v_type v;
v_type::const_iterator p = v.begin();
or
template<typename Iterator> void do_something(Iterator p);
do_something(v.begin());
typeof!
32 :
27:2005/05/25(水) 11:42:12
>>28 どうもありがとうございました。
ところでちょこっとスレ違いになりそうな気もしますが、
文字列って27のようにスコープ外れたり極端な例でいえば
char* getString()
{
char* p = "HogeHogeHoge";
return p;
}
みたいな文字列でもプログラムの実行中は生きてるのでしょうか?
char*をconst char*に変えれば、そのプログラムは無問題
char *に文字列リテラルを代入できるのはCとの互換性のため。
36 :
デフォルトの名無しさん:2005/05/27(金) 06:27:32
vectorをシャフルする方法を教えてください
vectorをシャフル?
単にstd::random_shuffleを知らないってだけの話なのか、
それとも何かひねったこと訊いてるのか。
38 :
デフォルトの名無しさん:2005/05/28(土) 00:01:46
初心者なんですが教えてください。
市販の本で、STLのvectorとかlistの説明で
vector<char>
とか
list<int>
とか簡単な例が載っていますが、これってほとんど実用性がありません。
で、考えたのですが、例えば構造体のポインタ(アドレス)を格納するようにして、
#include <vector>
using namespace std;
struct Hoge
{
double A[ 3];
int B[ 5];
};
vector<Hoge*> VHoge;
などとして、
Hoge* T=new Hoge;
VHoge.push_back(T);
:
:
とかってやったらかなり便利かな、と思ったのですが、
こういう例って見たこと無いんです。
ポインタ(アドレス)を要素に使っちゃダメとかいうことってあるのでしょうか?
問題ない
ただ、deleteするのを忘れるなよ
41 :
デフォルトの名無しさん:2005/05/28(土) 00:05:39
>>38 文法的には全然問題ないが、動的に確保したオブジェクトを生ポインタで持つのはタブー。
boostかLokiあたりのスマートポインタを使うべし。
>これってほとんど実用性がありません。
んなこたぁ無い。
43 :
デフォルトの名無しさん:2005/05/28(土) 00:07:31
>>42 >動的に確保したオブジェクトを生ポインタで持つのはタブー。
誰のタブーだよ?
標準に無いものを安易にすすめるなと言いたい
45 :
デフォルトの名無しさん:2005/05/28(土) 00:08:30
マイタブーと思われ。。。
>>43 一般論だぞ。
たとえば38のpush_backが例外を投げたらHogeが一個リークする。
>>44 確かにそうだがauto_ptrは使えないのでしょうがない。
47 :
デフォルトの名無しさん:2005/05/28(土) 00:14:41
vector<Hoge*> VHoge;
を
vector<Hoge> VHoge;
とやったら、構造体(クラス)Hogeに標準コンストラクタと
演算子<と==を定義しないといけないんですよね。
となると、やっぱりアドレス格納方式のほうが良いかなぁ、と思いますが。。。
49 :
47:2005/05/28(土) 00:17:13
>>49 そうではなく
> とやったら、構造体(クラス)Hogeに標準コンストラクタと
> 演算子<と==を定義しないといけないんですよね。
は何の話だって事。
どっから仕入れた。
51 :
デフォルトの名無しさん:2005/05/28(土) 00:29:48
smartpointerだと例外投げられても delete hoge してくれるのか?
どうやってんだ?
っていうかまったくsmartptr知らないんだけどさ。
>>47を見て、え!?と思った人が、日本全国で3人ぐらいいると思う。
>>51 boostのshared_ptrみたいなスマートポインタは、デストラクタで
確実に資源の解放をする
Stroustrupの「資源の獲得は初期化である」戦術に沿ってるわけだ。
つか、それをやらないと例外安全なコードが書けないのがC++。
54 :
デフォルトの名無しさん:2005/05/28(土) 00:37:59
ベクトルを使ってオブジェクトを格納する場合、
クラスがデフォルトのコンストラクタを定義し、
<と==の演算子のオーバーロードバージョンを提供する必要あり、
って手元の本には書いてあるよー。
コンパイラのSTLの実装方法によっては、その他の比較演算子も
必要になることもあるって。( ^∀^)つ" ∩ヘェー
>>54 STL使うときって面倒くさいね。
かなり巨大なクラスになってからだと、やっかいだな。
そもそも、比較演算なんて想定していないクラスはどーすんだ?
>>55 STLが予期しない結果や動きをすることもあるってことだろ?
これまでの原因不明のバグは、これだったのかと...orz
比較をしないなら比較が必要なコードはコンパイルされない
ゆえにエラーにならない
んじゃなかったか
58 :
51:2005/05/28(土) 00:42:27
>>53 >スマートポインタは、デストラクタで確実に資源の解放をする
それは予想内のことだけど、そのスマートポインタのデストラクタが、
例外が投げられた後どうやって呼ばれるかと疑問に思っているわけだが?
>>58 なんだかよくわからんな。スタック巻き戻しの際にデストラクタをいちいち
よんでやるのはC++の基本機能だろ。
そういえば、俺の恩師は、STLを真に理解している人は、
世界に5人しかいないだろうって言ってたな。
>>57 コンパイルされないと実行時どうなっちゃう?
比較されないから、結果は不定とか。
>>61 あのね、実行時必要になるような(=つかってる)コードはもちろん
コンパイルされるの。
ぜんぜん使ってないコードは、コンパイルされないわけ。
もちろんテンプレートに限った話だよ。
>>54 そうなのか?本のタイトルは?
俺の本(Generic Programming -STLによる汎用プログラミング-)には
vector< T >
型の要件: T は代入型のモデルである。
代入型
有効な式:
X(x); x は X のオブジェクト、X(x) は x のコピー。
X x(y); y は X のオブジェクト、y は x のコピー。
x = y; 戻り値の型はX&、x は y のコピー。
とあるぞ。
あるいは最後の x = y だけを以って代入型とする場合もある。
>>60 最近はもっと増えた思う。
>>63 ダイナミックリンクならぬダイナミックコンパイルみたいだ。
Assignableである必要すらなかったと思うんだが、記憶違いかな。
67 :
51:2005/05/28(土) 00:50:05
>>59 一体どういうスコープなのそれって?
スタックにsmartpointerをインスタンス化するってこと?
そんなんじゃ、そのvector自体、関数内のローカルな寿命でしかないじゃん。
使えないよそれじゃ。
>>65 そうそう、テンプレートはそういう面倒くささと高度な技術を
実装系にもとめちゃうわけ。
初期のCfrontは、とりあえずリンクしてみて、(テンプレートがらみで)
たりないものがあったら再度コンパイラを走らせる
みたいな実装だったらしいよ。
>>51 まあ君がなにも分かっていないことが、よくわかった
C++にはテンプレートの型の要件を明示する機能はないし
コンパイルエラーが意味不明になりがちなのは欠点だよね
71 :
51:2005/05/28(土) 00:56:49
>>69 まぁ、キミは表面的な理解しかしてないが、とりあえず「スマートポインタ」
とか言ってみたかっただけだという事が判った。
>>67 vector破棄->スマートポインタ破棄->オブジェクト破棄
の連鎖が成り立つことが重要。
そのvector自体もスマートポインタで管理されてるかも知れないけど、
連鎖を逆にたどっていっていつかはローカル変数にたどり着くなら、
その関数が例外で終了したときにすべて破棄されることが保障される。
>>64 標準講座C++
基礎からSTLを利用したプログラミングまで
P559、P565あたりかな。
intやcharの組み込み型は既に用件を見てしているから無問題だって。
ユーザーが定義した型(構造体やクラス)だと必要なのかな?
75 :
51:2005/05/28(土) 01:01:31
>>72 そうだね。たとえ行き着く先のsmartptrがstaticであっても破棄されるね。
STL使うためだけに演算子定義するの面倒だー。
オブジェクトの集合が順序集合じゃなきゃダメってことか?
なんか使いにくいのねー。
>>76 いやだから、比較が必要なコンテナやアルゴリズム、メソッドが
使えないというだけ
>>76 vector使うだけなら要らんぞ。mapは必要だがな。
ここって良スレだね。
>>67 スタック巻き戻しだけでなく、
コンストラクタの最中におちた場合にも、基底やそん中で生成された
オブジェクトのデストラクタは起動されるし、
何かがdelete(delete[])される際には、そのオブジェクトの
デストラクタは起動される。
これ以上の確実性は、手作業では保証できんのよ。だから、「資源獲得は
初期化である」テーゼが重要なの。
クラスは回らない寿司屋の板前みたいに格式ばってるが
テンプレートはファーストフードのマニュアル対応みたいなもん
インターフェースだけあわせておけばとりあえず店員として通用する
それがテンプレートクオリティ
STLの唯一の間違いは、
インターフェースにクラスを強要してしまっていることだ
つまりファーストフードの店員に板前の真似事を無理矢理強要させるのと同じ
そのインタフェースが言語機能的には明示されないのが欠点なんだけどね
85 :
51:2005/05/28(土) 01:11:39
>>81 もう判った。ごめんごめん。
あとは、pointee_ に代入するオーバーヘッドの問題だけだな。
>>83 それは違う
組み込み型や組み込みの配列やただの関数ポインタが使えるのが
STLのいいとこじゃないか
なんかレベルが高くなってきたのでそろそろねまつ。
みなさん、ありがとうございました。
>83
>インターフェースにクラスを強要してしまっていることだ
これは,例えばコンテナの要件がbeginやendなどをメンバ関数として実装していることを
要求していることを指している,と解釈して良いですか?
で,これを
>STLの唯一の間違い
と指摘する具体的な理由も聞いてみたいです.後半の
>つまりファーストフードの店員に板前の真似事を無理矢理強要させるのと同じ
という文章だけだと抽象的過ぎてあまり良く理解できなかったので・・・.
89 :
デフォルトの名無しさん:2005/05/28(土) 06:51:55
begin endの実装なんて、
ファーストフードの店員にスマイルを強要する程度じゃないか?
いったん比喩を取っ払わないと
以後数十レスほど混沌とし続ける予感
二次元のベクトル
vector< vector< double > > x(SIZEX, vector< double >(SIZEY));
はうまくいくのですが
vector< vector< vector< double > > > x(SIZEX, vector< double >(SIZEY),vector< vector< double > >(SIZEZ));
3次元の場合、コンパイルエラーになります。
どこが間違えているのでしょうか?
>>91 こうじゃないか?
vector<vector<vector< double > > > x(SIZEX, vector<vector<double > >(SIZEY, vector<double>(SIZEZ)));
コンテナがクラスなのは失敗どころかむしろ歓迎すべきだろ。
ちょっとした開発環境ならメンバ関数の候補を出す機能くらい備えてる。
これが関数ベースだとそうは行かない。
特に関数テンプレートはそのパラメータが受け取れる型についてプログラマに殆ど情報を与えてくれない。
push_front( vec, val );
が正しいかどうかはコンパイルしてみないと判断できない。
STLの実装によっては問題なくこれを受け入れてしまうかもしれない。
むしろvector< bool >のほうがよっぽど大きな間違いだろう。
どっちみち<algorithm>の関数類を使うからして
メンバ関数だけ候補出してもらってもさほどうれしくない
全部関数の方が、見た目の統一性があってよかったよ
要件の記述がC++言語内で標準的に出来たらさぞ幸せだろうなぁ。
標準など幻想
>>95 D&Eにテンプレート引数に対する要件を記述するテクニクみたいなのが
載っていたよ
あくまでテクニクでありtipsだけど
そろそろC++の次期仕様を作るべきだな。
Cとの互換性はそろそろ犠牲にしてもよし。
あとvector<bool>を思いついたバカをこの機会に処刑。
そんなもん誰も使ってないんだから実害なし。
本からの知識をひけらかすのは楽しいものだが
処刑確定だろ
むしろstd::vector<bool>こそ知識をひけらかす為に作ったもの。
とりあえず規格をさらっと見てみたところではコンテナの要素についての要求は
以下の通り。
・23.1-3 から要素の型は CopyConstrutible でかつ Assignable である必要がある。
・Sequence(vector, deque, list)については他になさそう。
・Associative container(set,map,multiset,multimap)については key の比較が必要
だけど、同値は比較から導出するから必要ない(23.1.2-3)。
テンプレートで指定してやれば、比較が operator < である必要はない。
無論、各メンバ関数では remove で operator == が必要、だとかさらに要求が
つく場合はあるけど。
で、関係ないけど恥ずかしながらポインタの比較について知らなかったことを晒してみる。
・同じオブジェクトを指している場合、同じ配列中の要素を指している場合以外に、
同じ集成体(構造体等)のメンバを指している場合もポインタの比較が規定されている。・ただしアクセス指定子で分けられている場合を除く。
・C では規定外の場合は未定義、C++ では不定
んが、20.3.3-8 で
>For templates greater, less, greater_equal, and less_equal, the
>specializations for any pointer type yield a total order, even if
>the built-in operators <, >, <=, >= do not.
とされているため、ポインタを associative container などに突っ込むことができる、と。
逆に規格を厳密に解釈した場合、例えば list<T*> に対して sort() は意味のある結果を
返さないかもしれないが、sort(less<T*>) は意味のある結果を返すということになるね。
後、おまいら STL における比較は strict weak ordering が必要って知ってましたか?
>98
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#96 vector<bool> はやめて別の名前にする方針みたいっすよ?
しかしま、豪快なタイトルですな。
>>102 参考になった。乙。
>後、おまいら STL における比較は strict weak ordering が必要って知ってましたか?
当たり前だと思ってたんだが、何か意外な点でもあるのか?
104 :
デフォルトの名無しさん:2005/05/29(日) 00:12:36
vector<bool>って何がおかしいの?
106 :
デフォルトの名無しさん:2005/05/29(日) 00:31:44
意味わかりません
boolの配列は作れないということですか?
俺はvector<bool>::pointerとvector<bool>::referenceやそれのconst版が
実際にはポインタや参照ではないことがまずいと読んだが。
vector<bool> vec;
vec.push_back(true);
bool* p = &vec[0];
ができないわけだな
>103
いえ、結果からすれば当たり前ではあるんですが無意識のうちに使っていたもので。
一度 strict weak ordering というのをおいてから equivalence を導出して、最終的に同値類での strict な全順序を
持ってくるところと、
・comp(a,a) は常に false
・comp(a,b) && comp(b,c) ならば comp(a,c)
・equiv(a, b) を !comp(a,b) && !comp(b,a) として equiv(a,b) && equiv(b,c) ならば equiv(a,c)
という 3 つの制約で定義しているのが面白い、と。
確かに、これで comp(a,b) と comp(b,a) が同時に成立しない、とか最終結果が出てくるんですよね。
後、単純に比較させるだけなら ≦ を使っても良かったと思うんですけど、そうしなかったのは
equality と equivalence とを区別する意味からなんだろうなぁとか。
と思ったら、既にそんなことを書かれてる人がいますね。
ttp://d.hatena.ne.jp/Cryolite/20040529
112 :
デフォルトの名無しさん:2005/05/31(火) 12:32:37
ifstreamのバイナリモードで、テキストファイルをget()で1文字ずつ読んでいます。
なぜか、eofの前に余計な1バイトをget()してしまいます。
テキストファイルをバイナリエディタで開いて確認しても、そんな文字はないのですが
どういうことでしょうか?
>>112 というか、一度でもいいから、テキストファイルをバイナリエディタで
覗いてみろと小一時間。
115 :
デフォルトの名無しさん:2005/05/31(火) 12:55:52
>>113 ifstream.eof()の前に、get()が"4294967295"という値を取得してしまうんです。
>>115 どうしてもeof()を使いたいなら、istream& istream::get(char& c); を
使った方がいいよ。ストリームがeofになったら、cの値を捨てればいいから。
118 :
デフォルトの名無しさん:2005/05/31(火) 14:46:38
>>116 よく、
while(!in.eof()){
c = in.get();
..色々処理
}
ってソース見るけど、
while(!in.eof()){
c = in.get();
if(!in.eof()){
..色々処理
}
}
にしなきゃいけないの?(getして値を使う前にeofチェック??)
とりあえず上記で解決したようですが。
>>118 117の言うように、
char c;
while(!in.get(c).eof()){
// 色々処理
}
とするのがわかりやすいんじゃないか。
>>119 スマン。すぐ終わる。
>>118 CもC++も、値を読み込んで初めてEOFかどうか判断できる。
その書き方はBASICのそれだ。
istream& istream::get(char& c);は返却値がistreamなんだから、
operator !() を使って、
while (!in.get(c)) {
なんかの処理
}
とやるのがスマートだろう。
これは余談だが、C++でfstream関連についてあまり分かってない人が
多い。多分cstdioを使う方が速いからだろうが、大学で情報処理を
とってきた人でもfstreamはさっぱり・・・・という人がほとんどだ・・・orz
俺もstream系はさっぱりだ。
多分抽象化し過ぎなんだよな。
a << "aaa" << "bbb" << endl;
これはC系言語C++にとって異質。
性能が(少なくとも)昔は悪かったとか
クラス階層が複雑だとか
ものによっては入力系の先読みがウザいとか
まあ嫌う理由はいろいろあるな
複雑なフォーマットとか、printf系では一発でも
iostreamではゴテゴテとしたマニュピレータが必要になるし。
mingw-gccでサイズが一気に200KB超えるのが嫌だな、printfだけなら10KBですむのに、
iostreamは仮想継承で全部の階層の全部の関数がリンクされるそうだから。
boostのlexical_castやformatもstream& operator>>(stream& o, ...)を使ってるのでデカデカになる。
char c;
while (in.get(c)) {
処理
}
だと思うのだが。
>125
ケチケチすんなよ
>>125 MinGW+STLportなら、-D_STLP_USE_DYNAMIC_LIB をコンパイルオプション
に指定して主要部分をDLLに追い出せば、プログラムをたくさん作っても、
ほとんどCと変わらんよ。
速度的には、そりゃあ多量のデータをファイルに書いたり読んだりすれば遅いけど、
小さなデータならあっという間だし、現時点でcstdioを使う必要はあまりなくなって
来たなあ。意味があるとすれば、ベンチマーク時くらいかね。
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?
MS本社の方にむかって3回土下座をすると直ります。
MS本社の場所はサポートセンターに問い合わせてください。
#include "stdafx.h"
後氏ね。
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
100過ぎてやらんでいい
ていうかスレ違うし
しかし住人は違わなかったわけだw
sizeof(std::size_t)は32ビット処理系で4,64ビット処理系で8・・・・以下略
は保証されているんだっけ?
ついでにsizeof(char)は1で8ビットは保証されているんだっけ?
言語規格での保証ならsizeof(char) == 1だけ
std::size_tはたしかsizeof演算子が返す値の型と定義されている。
charは8ビット「以上」でなければならない。(<climits>のCHAR_BITS)
8ビットでなくても良いということだな。
いや、俺の環境では -1 より小さいらしい。
std::cout << (sizeof(char) < -1) << std::endl;
つ default promotion rule
143 :
137:2005/06/02(木) 16:19:17
レスサンクス
・・・numeric_limitsで場合わけするか。
144 :
デフォルトの名無しさん:2005/06/03(金) 09:29:18
独自のメモリー管理機能をもったライブラリーを使ってる。
(画像処理のライブラリー)
STLのデフォルトアロケータと何か問題を起こしてるみたいだ。
std::vector<char> newVec(10)
でこける
なんとかならないのか
環境はVC++.net2003
自分でアロケータ書け
>>144 boost::poolでも使ってみろ。
> STLのデフォルトアロケータと何か問題を起こしてるみたいだ。
糞だなw
>>144 多分、その「独自のメモリー管理機能」にバグが残っていると見た。
STLのせいにする点で、糞。
STLに干渉しようしている時点でやばい
152 :
デフォルトの名無しさん:2005/06/03(金) 13:40:29
2次元のvector
vector< vector< int > > vwork(X, vector<int> (Y))
でYの部分をなぜ(Y)にしないと、コンパイルエラーが起きるのでしょうか?
ちなみにその画像処理ライブラリーというのは
OpenCVとIPL
IPLは基本部分がバイナリーで与えられてるので改造できない。
アロケーターにバグあっても対処できね
>>152 vector<int>(Y) がコンストラクタだと気付いてないとしても
vector<int> Y が文法的におかしいことには気付いて欲しい。
>>144 そもそもなぜこれでこけるのかが分からない。
operator newの置き換えでもやってるんだろうか?
vector<Base> に Base から派生したclass を挿入するのは
文法的に禁止されているのでしょうか?
class Base
{
public:
Base(){}
};
class Derived : public Base
{
int hoge_;
public:
Derived(int hoge):hoge_(hoge){}
int test() {return hoge_;}
};
int main()
{
Derived a(3);
vector<Base> b_list;
b_list.push_back(a);
Derived& b = static_cast<Derived&>(b_list[0]);
cout << b.test() << endl;
}
上のコードをコンパイル・実行すると 3 が出力される事を
期待しているのですが不定値が出力されてしまいます。
(環境: Intel compiler 8.1 Windows版)
上の例は文法的に間違っているかどうか、詳しい方がいらっしゃいました
らご教授ください。m(__)m
文法的には間違っちゃいないが(コンパイル通ってるんだし)
常識的には間違っている。スライシングが起こるから。
vector じゃなくても、
Base b = Derived();
とかやると何が起こるか考えてみよう。
>>157 vector<Base>に何か入れようとするとコピーコンストラクタが発生して
Derivedを入れようとしてもBaseのオブジェクトとして格納される。
こういうときにはBase *とかboost::shared_ptr<Base>をvectorに入れるようにすれば良い。
160 :
157:2005/06/04(土) 00:31:38
>>158 >>159 お二人とも素早いレス、どうもありがとうございます。
大いに勉強になりました。なるほど、スライシングですね。
Base* を利用してみる事にします。
とても助かりました。ありがとうございます!
m(__)m m(__)m m(__)m m(__)m
163 :
162:2005/06/04(土) 22:31:24
>>129 それがdllのメリットじゃん。
なにか疑問でも?
165 :
デフォルトの名無しさん:2005/06/05(日) 00:15:30
>>12 でもVC以外のSTLの準拠率が話題に上ることはあまりないな…
他は全て完全準拠してるのか!?
VCのシリアライズを使うと
クラスの内容をファイルに簡単に書き出せるけど
stlのコンテナにシリアライズはできないの?
>>168 つ[boost::Serialization]
boostってstl?
173 :
デフォルトの名無しさん:2005/06/05(日) 14:05:29
stringのc_str()が返すポインタは、いつまで有効なのでしょうか?
またこの関数を使う上で注意点ってありますか?
174 :
デフォルトの名無しさん:2005/06/05(日) 14:14:09
>>173 >stringのc_str()が返すポインタは、いつまで有効なのでしょうか?
次にそのstringの非constメンバ関数を呼ぶまで。
string str = hogehoge();
const char* cp = str.c_str();
if (str[0] == '$') {
とやったら、3行目でおじゃんかよ
ほんとかよ?
>>175 ほんとです。
COWで実装されてたらあたりまえだろう。
ふーん
ま、Writeしてないのに、勝手にCopyしてリソースを浪費するのは
実装として話にならんと思うが・・・
178 :
176:2005/06/05(日) 14:57:58
>>177 ごめん。比較が代入に見えてた。
「あたりまえ」ってのは言い過ぎだな。
179 :
デフォルトの名無しさん:2005/06/05(日) 15:11:10
非constメンバ関数が呼ばれた時点でWriteされたと見なすしかないだろ。
operator[]がプロキシを返すことは許されてないんだし。
operator=はconst関数だな
181 :
180:2005/06/05(日) 15:12:49
C++の言語定義上はね
その定義がなんとも不自然だなあと思うだけで
まあ、最近は多くのbasic_stringが
COWを使わなくなったからどうでもいいんだが。
>184
実装が終端に'\n'を持つかどうかの自由度を残したんじゃないですかね?
ちなみに
template<class T>
T const &as_const(T &x){ return x; }
char const *cp = str.c_str();
if(as_const(str)[0] == '$'){
は安全ですね.
187 :
デフォルトの名無しさん:2005/06/05(日) 23:57:32
c_str()のポインタはstrdupでコピーしておくのが一番安全。
>>187 なんでやねん。stringに代入したりすると、ポインタが変わったりするぞ?
>>187 そんなことするぐらいなら string をコピーしとけばいいだろ。
>>187 釣られてみる。
strdup()は、「標準に含まれていない」という理由だけでも使う価値はない。
百歩譲ったとしても、「strdup()が確保するメモリの開放方法はない」という
点においてもまた、使うべきでない。
昔からこんな関数考えたやつの気が知れんのだが。
>>190 > strdup()が確保するメモリの開放方法はない
は?free()すればいいのでは?
> 昔からこんな関数考えたやつの気が知れんのだが。
char * p = malloc(strlen(s)+1);
strcpy(p, s);
と毎回書くのが面倒だったからでしょ。
>>191 規格にない以上、strdup()が確保したメモリがfree()で開放されるとは
保証されていない。
>>192 規格に無い関数の仕様を規格で判断してどないすんだっちゅーの。
「CreateWindowは規格に無い以上、その動作は保証されていない」
とか言うのかよ。
現実問題として、free()で開放できないstrdup()の実装なんぞ
見たことがないぞ。
非標準ライブラリなんだから非標準のドキュメントを参照するべきだろ。
>>193 >「CreateWindowは〜」
その通り。
>現実問題
書いてないことは決まっていない。
>>194 その通り。
なら規格厳密合致の清く正しい世界で生きてくれや
俺はGUIやsocketやDBの存在する現実の世界で生きるから
>百歩譲ったとしても、「strdup()が確保するメモリの開放方法はない」という
言い切っちゃうところがすごいねw
198 :
デフォルトの名無しさん:2005/06/06(月) 01:15:08
>>197 メモリの開放方法ってどこに書いてあるの?
>>198 たとえばこんな風にだ(これはfreeBSDのmanからの引用)
The strdup() function allocates sufficient memory for a copy of the
string str, does the copy, and returns a pointer to it. The pointer may
subsequently be used as an argument to the function free(3).
規格に無いということはstrdup()は独自のメモリ管理をしているに決まっている。
だからfree()できない。
なんだかわからんが、string::c_str()じゃだめなのか?
>>200 はいはい、規格に無いんだったら free() できる仕様かもしれないし、そうでないかもしれないし、
あんまり短い文章で論理破綻しないでくれよ。
>>197 規格厳密合致がこんだけ好きなくせにどうして規格にないことが言い切れるんだろうね
>>200 規格にない関数は独自のメモリ管理をしなくてはならないなんて規格には書いてない。
皆さんなんか物凄くレベルが低くなってますんでこの辺でdupの話題は打ち切りということで。
そうだな。dup()なんて規格に書いてねーからそれがfile descripterを
複製してくれるとは限らないしな。
今まで標準だと信じて使ってきたstrdup()が、ここに来ていきなり
否定されてファビョっている奴。情けねー
まあ一つ言えるのは、strdup()はSTLとは何の関係も無いことなのだが。
>>210 余程悔しいようだな。strdup()は 非 標 準 で す。
>>211 よほど日本語が読めないようですが、誰もstrdup()を否定してません。
ファビョるっていってるくらいだから、かの国由来なのかな。
>>212 よく読め。strdup()なんかを薦めてしまった
>>187と
strdup()をものすごい勢いで否定してる
>>190と
それを肴に悪乗りしてるその他大勢がいるだけだから。
そうですよ。今度はちゃんと読めましたね。
217 :
デフォルトの名無しさん:2005/06/06(月) 03:40:12
月の輪クマの映像まじびびった。宇宙人が轢かれたのかとおもた。
219 :
デフォルトの名無しさん:2005/06/06(月) 03:46:44
>>218 どっかの高速道路の事故現場の中継で、つきのわぐまの轢死体が写ってた。
strdupはX/OPENらしい
COWってCopy On Writeか。
牛が思い浮かんで笑えたんで。
>>222 実際、COW が嫌いな人は Mad COW Disease なんて呼んだりもする。
ライスおばさんの顔が浮かんだ
copy-on-write って書くから無問題
STLとあまり関係のない牛の話をするスレはここですか。
227 :
デフォルトの名無しさん:2005/06/07(火) 13:21:52
違います
牛は標準ですか、非標準ですか。
標準は狂牛病かどうかは気にしない。
230 :
144:2005/06/07(火) 18:43:15
原因判明
iplでは
画像格納してるの先頭のポインターのアドレスがなぜか
変動する
境界判定を省略するために
バッファを大きめにとって
バッファ先頭+画像横幅+1あたりにポインタを移動してるとか
そういえばゲートウェイって日本市場復活したんだっけ?
std::vector<float>の中身が
ちゃんとメモリーのアドレスどおりに並んでない場合ってあるの?
std::vector<float> vf(10)
float *p_float= vf..begin()
なら
p_float[0]==vf[0]
p_float[1]==vf[1]
p_float[2]==vf[2]
...
だよね? ならない場合ってあるの?
>>233 std::vector<bool>を除くstd::vector<>は、配列と同じメモリレイアウトに
なっていることが保証されている。
begin()の前のドットは1つな。
>>233 アドレス通りに並んでいることは保証されているけど、
vector<float>::begin()が返す型であるvector<float>::iterator型が
float型のtypedefである保証は無い。
float *p_float= &vf[0];
とやらなきゃダメ。
&*vf.begin()とか&vf.front()とか方法はいろいろ。
まさかとは思うが、begin()を取り出した後にpush_back()とかerase()とかしてないよな?
サイズ変更しない関数呼ばなければ、中身のアドレスは変わらないことが保証されているぞ。
プログラミング言語C++嫁。
> サイズ変更しない関数呼ばなければ
サイズ変更する関数呼ばなければ
の間違いか
あ、スマソ
こんにちは
質問ですが、
std::wstring wstr;
で
wstr.c_str()はwchar_t*を返しますが、
char*(マルチバイト文字)を返す関数、または方法はありますか?
できれば、一つの関数でchar*を得たいのですが。
よろしくお願いいたします。
242 :
デフォルトの名無しさん:2005/06/10(金) 13:56:52
一応あげときます。
>>241 DBCS -> MBCSに変換したいっつーことか?
244 :
241:2005/06/10(金) 14:14:16
>>243 いえ、変換の仕方は知ってますが、
std::wstring wstr;
を関数一つの呼び出しでchar*を得られるものがあるのかどうかを知りたいだけです。
たぶん無いと思いますが。
>>244 std::wstringにそういうメンバ関数はない。
qsortにstd::vectorの配列先頭ポインタを渡したいのですが、
得る方法はありませんか?
&v[0]
すでにFAQだな。
まあいいだろ。話題ないし。
とは言え、11コ上のレスも読まない/読めないなんてのは。
基本的にqsortでなくsort使うべきだが
vectorを使っておきながらqsort使う理由はないわなあ
コンストラクタが重いからという理由以外はな
ベクターをソートするときってコピーコンストラクタが呼ばれるんだよね?
vector<HOGETYPE*>でなく、こんなvector<HOGETYPE>だったら、かなり痛いよね。
class HOGETYPE{
...
hoge& operator = ( const hoge& right ) {
if( ptr ) { delete ptr; ptr = new float[NUM]; memcopy( ptr, right.ptr, NUM*sizeof(float)) }
}
float* ptr;
};
vector<HOGETYPE> buffer;
おまけに、
swap( T& a, T& b ) { T temp = a; a = b; b = temp; }
なので、1回の並べ替えでコピーコンストラクタが3回も呼ばれる。
↑間違い
class HOGETYPE{
...
hoge& operator = ( const hoge& right ) {
if( ptr ) { delete ptr; }
ptr = new float[NUM]; memcopy( ptr, right.ptr, NUM*sizeof(float)) }
}
float* ptr;
};
代入できるクラスを書くときは必ずstd::swapを特殊化するとか。
>>253 swap を特殊化すれば回避できるだろう。
>>253 あれだよな、vector<HOGE*>だと関数オブジェクト書くのがめんどいんだよな。
vector<HOGE>だとHOGEの実装をハンドル持つようにして=の最適化かvectorっぽくswapの特殊化だよな。
>>255 まじで全部特殊化してんの?
>>254 関係ない部分だが、 delete ptr の前の if( ptr ) は冗長だぞ。
>>255 >>256 std::swapを特殊化してもそれらがstd::sortから呼ばれる保証はどこにもないですよ.
それにクラステンプレートの場合std::swapを特殊化することができないです.
んな苦労せずに、qsort使えよ
うーんなるほど。
std::memcpyをコピーコンストラクタの代わりに用いるのは
C++では大抵の場合間違いだが、
この場合はそれでいいし効率も勝る訳か。特殊例だな。
>>260 やだよ。ソート基準が関数ポインタになっちゃうじゃん。
264 :
261:2005/06/11(土) 18:18:34
>>263 いやその、上の話に感心しただけなんだが、
実際にはオブジェクトのコピーではなくswapをしたい場合
>>262 じゃあ、listに入れてsortしろ
特殊化とかアホなことするの無意味
266 :
261:2005/06/11(土) 18:31:05
>>264 どこからmemcpyの話が出てきたんだ?
>>265 listはマージソートが出来るから、quick_sortの約1/2程度の速度でソートできる。
そのため、listにはメンバ関数にsort()が用意されている。
その他には、make_heapでヒープを作っておき、sort_heapでソートするという変態技
もあるが、RandomAccessIteratorを必要とするので、listには使えない。
268 :
261:2005/06/11(土) 18:36:11
>>266 おまえは偽者だな!!
おれが本物の
>>261だ!!
とかいうのはさておき、qsort()ならswapはmemcpy()つかてるでしょ
と思ったの。
でも、今VC++のCRTのソース見たら、swapするのにmemcpy()つかわず
なぜか手動でバイトコピーしてるな。
なんでだろう。
>>267 んな話じゃなくて、listならコンストラクタ走らねえってこと
いやvectorが向いてるかlistが向いてるかって他の要素も絡むし
重要だから
sort()でコピーコンストラクタを走らせないためだけにlistを
選ぶってのはどうかと
じゃあ、qsortだな
あるいは、無理やり同サイズの構造体にでもキャストして、sortを呼ぶか
swapの特殊化で済むならそれで良いんじゃねえの?
保障はないみたいだが。
swap以外にコンストラクタが走らないという保証もないだろ
つーか この問題は大規模オブジェクトのコストってやつで。
後置++とか+とかの演算子の一時オブジェクトのコピーについて、最適化としては=のコストを検討すること。
じゃねーの?
>>258 世の中にはnewしていないものをdeleteしたくない人だって居る。
世の中には↑のようなボケも居るんだな
>Using delete on a pointer to an object not allocated with new gives unpredictable results.
>You can, however, use delete on a pointer with the value 0.
ISOの規格は知らんが、MSDNにはこうあるな。
勉強になったな俺もお前も
if (p) delete p の方が、null時には速いだろうってことでないの?
↑今日一番のボケ発言だな
>>279 delete内でもNULLチェックぐらいやっているって。
NULL時に早くてもNULLばっかわたるわけでもない品
最適化効かなくても全然変わらなそう
VCだと最適化後の delete 0 でさえ、関数呼んでるという話を聞いたが
int* i=new int;
delete i;
delete i;
てやったら2回目のdeleteで堕ちた。。。
でも、
if(p) delete p;
にしといたほうが、おばかなコンパイラには優しそうだ。
冗長っても行数が増えてるわけじゃないし。
プログラマの気持ちが伝わってくるのはいいんじゃね?
大勢に影響は無いのは事実だし。
>>253 の例だけど、
・コピーコンストラクタの話なのに、なぜ HOGETYPE(const HOGETYPE&)
ではなく operator=( const hoge& right ) をあげているのでしょう?
・デフォルトコンストラクタには触れてないけど ptr は NULL に初期化なのか、
ptr = new float[NUM] なのかどっちのつもりでしょう?
・delete ptr ではなく delete [] ptr ではないでしょうか?
>>287 そりゃそうだ。
deleteはデストラクタを呼んでポインタの指す領域を解放するだけで、
ポインタ変数の値を0にしてくれはしない。
deleteしていいポインタかどうかを確認するには本来
null pointerかどうかのチェックでは不完全であって、deleteしちゃいけない
ケースは山のようにある
そして移植性の高い方法では、完全なチェックは事実上不可能だ
そういった中でnull pointerかどうか「だけ」をチェックするのは意味がないし、
そもそもnull pointerをdeleteするのは安全であることが
規格で保証されている以上、間抜けなコードだと言われても仕方が無かろう
>>287 ISO/IEC 14882:1998 5.3.5 Delete -4
[Note: the value of a pointer that refers to deallocated storage is indeterminate.]
んーでも、0だけは例外ね♪的な仕様の方が
本流から外れてる気がしないでもないが。
例えば、あるクラスがあってコンストラクタでnewして
デストラクタでdeleteするような設計だったならば
delete内のNULLチェックがそもそも冗長ってことになる。
まあ仕様で決まってるんだから、ウダウダ言っても仕方ないんだけれども。
>null pointerかどうかのチェックでは不完全であって、deleteしちゃいけない
>ケースは山のようにある
そんなケースある?
>>294 deleteしていいのは
newで確保されて、
まだ開放されておらず、
もう誰も使っていないポインタだけ
だろ
他のポインタは全部deleteしちゃだめ
int* i=NULL;
i=new int[ 100];
:
:
if(i) delete [ ] i;
i=NULL;
:
:
ってやってるほうが精神的に落ち着く自分がいる。
っていうか、ポインタ変数ってNULLで初期化しておくのが
定石かとおもたら違うの?
297 :
デフォルトの名無しさん:2005/06/12(日) 01:38:57
オレはコーディングの際、ポインタが未使用のときはNULL、
メモリを指しているときは!NULLであるということを徹底してる。
だから騒然、最初にポインタ変数宣言するときはNULLで初期化するし、
処理の途中でdeleteしたら必ずNULLを入れるようにしている。
deleteしっぱなしだと、使いまわしているポインタだと、
わけわからなくなるから、これはやめられない。
例えば、windows+DirectXのようなシングルデバイス,マルチスレッドだと以下のようなメソッドの構成になりがちだし、それぞれのメソッドが必ず一定の順序で呼ばれる保証も無い。というかそれを期待してはいけない。
したがって、NULLでポインタはinvalidであるという約束事にしておく必要がある。
HOGETYPE::HOGETYPE() { Resume(); }
HOGETYPE::~HOGETYPE() { Suspend(); };
void HOGETYPE::suspend() { if( ptr ) { delete[] ptr; ptr = NULL;} }
void HOGETYPE::resume() { if( ptr == NULL ) { ptr = HOGETYPE[size]; }
ちゃんと自分でポインタ管理してますよ、って
ソースでアピールする意味でもif(p) delete p;ってやるな。
俺ならだけど。
すごい勢いの自演だなぁ
>>296-297 0で初期化すると、実は2度deleteしているような分かりにくいバグを
発見するのが難しくなる。
一方で、0で初期化しないと、0で初期化していたときには何故か動いて
いたものが肝心なときに限って(納品の直前とか?)落ちることが多くなる。
どっちがいいかはジレンマですな。宗教戦争の予感がする。
>>301 それってプログラムをちゃんと組めてないだけ。
設計思想とかそういうレベルの話じゃない。
>>298 そのsuspend()は
単に
void HOGETYPE::suspend() { delete[] ptr; ptr = NULL; }
でいい気がするんだが
という話ではなくて?
deleteなりfreeなりをした後にポインタをNULLにセットするような
マクロを使うようなコードも良く見るね
>>302 全部自分でやれる内はいいが、ライブラリのような
ある程度使い方を他人に委譲せざる得ない場合もあるしねえ
>>301 deleteのときは必ずNULL代入するから、
2度deleteとかはありえないですよ。
>>305 それは自分が管理している範疇じゃないから、
原因特定するときも、むしろわかりやすいよ。
>>306 NULL代入したら、二度目のdeleteは実質的に安全になるからな。
でも、二度deleteを呼んでしまうこと自体はあり得て、それが
ソフトウェアクラッシュに結びつかないから、露見しにくくなる、と
>>301は言っているのだろう。
それをバグと言うべきかどうかは微妙なところだと思うが。
>>305 そんなときでも、使用していないポインタはNULLの原則は守れますよね。
>>308 ちゃんと、if(p) delete p; p=NULL;してるから
2度deleteは無いんです。はい。
まあ、つまらんこだわりです、はい。
ここはチャットルームかw
まあ、意識しているに越したことないんでね?
レベルが限りなく下がってる時に限って盛り上がる。これいかに。
strdup()しかり。
>>305 どちらにせよ、あなたのポインタを0にセットするとクラッシュするっていうバグが
「pointerをNULLで初期化すべきでない」という論の論拠にはならないってことだ。
使わないんだからNULLでいいじゃん、
って単純に思っちゃう私はおばかチャン?
NULLにしとけば、アクセス時に確実にクラッシュするから、
むしろバグ発見しやすいって思ってたんだけどな。
newし忘れとか、するタイミングを間違ってるとか。
えっと、シンプルに考えて、
デフォルトコンストラクタは黙ってれば
メンバ変数はNULLで初期化してくれるんですよね?
それはPODで明示的に呼び出したときだけ
ところで、std::vectorの効率のよいソートのしかたについては?
322 :
デフォルトの名無しさん:2005/06/12(日) 03:31:48
>>321 とりあえずstd::sortがstd::swapを
呼ぶと仮定して話を進める。
前述どおりソートを改良するにはswapの
特殊化が最適だろう。
swapも対象が4byteに収まるなら
デフォルトのインプリメントが最も速いが
4byteで収まらない場合、メモリへの書き戻しが
発生してストールする可能性が出る。
ならば強制的にレジスタのみを使ってswapをするようにしれば
速くなるのではないか?
具体的にはmmレジスタ or xmmレジスタをテンポラリに使って
値の交換を行う。この際ふたりはプリフェチを忘れないように。
では
>>321実験よろしく。
delete の後に NULL 入れるっていう人は、
アクセス前に全部 NULL チェック入れるの?
そうじゃないと中途半端だよね?
deleteなんてどうでもいいだろ。
後で判定に使いたきゃ0ポインタにしておけばいいし、delete後にすぐ変数破棄するなら0いれる意味は無い。
俺の前居た職場では、ポインタNULL初期化強制だった
int *ip = new int[Num];
は、NGで
int *ip = NULL;
ip = new int[Num];
だとよ、なんつうか地味に鬱なコード書かされる
理由を聞いても意味不明なこというだけだし
∧_∧
( ´∀`)すまぽ
サイズが4000KBほどの構造体のスワップを
1000回繰り返すテストを行ったら下記のようになった。
MMXは最適化は全然してなくてこれなんで結構使えるかも。
SSEにしたらもっとよくなるかな?
std::swap = 121532867 clock
std::memcpy = 149840084 clock
MMX = 26874815 clock
>325
ださっ...そんな部署なら移動してよかっただろ。
まあな、やめた理由の(とってもとっても小さい)一つだしな
昔からこういう規則になってるというのならいざ知らず
去年、突然意味不明に導入された規則なところがまた笑える
330 :
327:2005/06/12(日) 14:13:04
SSE対応の為、構造体のアライメントを8byteから16byteにしたら
std系まで速くなってしまった。
アライメントって大事なんだな、へたな最適化より効果あるし。
std::swap = 98215796
std::memcpy = 107130904
MMX = 26091994
SSE = 22441920
桁多すぎて見づらいよ
>>327 これってMMXは、下のようにmovqで64ビット単位で転送しているだけでその性能がでているの?
//VC.Net 2003
#include <iostream>
#include <iterator>
int main(int argc, char* argv[])
{
long data1[2] = {100, 200};
long data2[2] = {300, 400};
std::copy(data1, data1 + 2, std::ostream_iterator<long>(std::cout, " ")); std::cout << std::endl;
std::copy(data2, data2 + 2, std::ostream_iterator<long>(std::cout, " ")); std::cout << std::endl;
__asm {emms}
__asm{
movq mm0, data1
movq mm1, data2
movq data1, mm1
movq data2, mm0
}
__asm {emms}
std::copy(data1, data1 + 2, std::ostream_iterator<long>(std::cout, " ")); std::cout << std::endl;
std::copy(data2, data2 + 2, std::ostream_iterator<long>(std::cout, " ")); std::cout << std::endl;
return 0;
}
桁多すぎて見づらいよ
>>325 万人がそこまでやるやらないは別として、
何もわかっちゃいないアフォに強制するコードとしては、
そのほうがいいのかもしれない。
ポインタでヴァグを出しまくりのヤツには
仕方のない仕打ちかと思われ(アナタのことじゃないよ)。
それくらい普通に教育できないもんかな。
>>334 そんな奴にC++でコード書かせるなよ、と
っていうか、それが教育の一環だろw
そういう予防措置的コードを書く香具師に限ってバグを出す罠。
書かない香具師はもっと出す罠。
341 :
デフォルトの名無しさん:2005/06/12(日) 22:56:27
そもそも、ポインタ変数を繰り返し使うときって、
メモリが確保されているかいないかを判断するのって、
ポインタにNULLが入ってるかいないか以外にどうやって判断してるの?
なんか確認できる関数ってあったっけ?
>>341 何かを指すかもしれないし指さないかもしれないポインタに
0を入れて「何もさしていない」と明示するのは、今の話題とは違うだろ。
前のHOGETYPEのケースで、
swap を特殊化するならコピーする必要はないでしょ。
ポインタをswapすればいいだけ。
deleteするべきかどうかも判断できないし、
メモリリークやりたい放題したい放題だね。
>>342 だから「そもそも」って改めて聞いてるんだけど。。。
おとなしくスマートポインタつかっとけ
new/deleteなんてカワイイもんだろ
COMのAddRef()/Release()に比べりゃよっぽど管理しやすい
>>349 ふつー CComPtr か CComQIPtr 使うでしょ。
そんな存在すら知らなかった漏れはboost::move_ptr使ってた
単に初期化強制でいいのにNULL初期化強制してるのが突っ込みどころなんでしょ
質問ですが、
std:vectorは、デフォルトで、どれだけのサイズが設定されているのでしょうか?
たとえば、
std::vector<int> nVal:
とすれば、デフォルトのベクター配列のサイズというものがあると思いますが。
>>354 引数無しのコンストラクタで初期化したら初期サイズは0だよ。
std::vector はデザパタの Composite の一種と言えるのでしょうか?
>>356 すごい質問だな。
C++ で Composite パターンを実装するときに
std::vector を用いることはあるかもしれないけど・・・
>354
capacity() については規定されてなさげ。以下、俺メモ。
> 23.2.4.1
> Complexity: The constructor template <class InputIterator> vector(InputIterator first, InputIterator last)
> makes only N calls to the copy constructor of T (where N is the distance between first and last) and
> no reallocations if iterators first and last are of forward, bidirectional, or random access categories.
> It makes order N calls to the copy constructor of T and order logN reallocations if they are just input
> iterators.
no reallocations ということは最初に要素数を調べて最低でもその分は capacity() を確保しておく、と。
InputIterator の場合は、reallocation が発生するので N ではなくて O(N) のコピーコンストラクタ呼び出しが発生する、と。
O(logN) の reallocation ということは、capacity() を倍々にしていく、みたいな方法がとられると考えられる、と。
データをソートして格納するコンテナにずっとmapを使っているのですが、
priority_queueとの違いがよくわかりません。
単にインターフェースが違うだけなのか、それとも計算量自体異なるのか…。
両方とも2分木探索をしているのではないですか?
>>360 mapの「ソートされている」という性質はあくまで二次的なもので、
「key-valueのペアを格納し、keyを指定しての高速なデータアクセスを提供する」
のがmapの目的。
全然違うでしょ。
>>360 priority_queueにはempty(),size(),top(),pop(),push()しかなく、内部では
heapを使っている。
mapはその他たくさんのメンバを持っていて、2分木探索をしているという
保証まではしていない(計算量のみ)。
363 :
360:2005/06/17(金) 00:47:39
どうもありがとうございます。
>>361 ソートされているという性質が二次的なものであったとしても、
実際問題、イテレータを使ってpriority順にアクセスできるのであれば
目的に適っていると思うのですが…。
そうしたい場合のpriority_queueの効率がmapよりも優れている、
というのであれば納得です。
>>362 heapもmapも、要素挿入は対数時間、priority最大要素の取得は定数時間、
という認識は間違っていないでしょうか??
2分木探索をしている保証はなくても、計算量が保証されていれば私としては十分なのですが…。
364 :
360:2005/06/17(金) 00:49:04
分かりにくくてスミマセン。
つまり、聞きたかったことはpriority_queueの存在意義です。
とりあえず省スペースではあるよね。
まあその分、make_heapするたびにコピーとかいっぱいしてそう。
>>365 std::priority_queue<>::push()ではstd::push_heap()を、std::priority_queue<>::pop()
ではstd::pop_heap()を使っているだろうし(少なくともそうしたときと同じ効果である
事が保証されているから)、毎回std::make_heap()するわけじゃないからそこまで
なさそう。
>>364 ということで、計算量の保証に対する認識としては正しい。std::map<>というよりも
std::set<>の方が近いかもしれないけれども。std::priority_queue<>自体は、感覚と
してはstd::make_heap()、std::push_heap()、std::pop_heap()とコンテナをカプセル化
したと考えればいい。普通の実装を考えればstd::set<>の方が各ノードのポインタ
の分余計にスペースをとっているから、その分単なるシーケンスである
std::priority_queue<>の方が省スペースだろう。もしかしたらstd::set<>の方が挿入
や削除に時間がかかるかもしれない。例えば赤黒木で実装されていたら木の組み
換えの際にビット操作を行っている場合もある。計算量の保証だけで十分なので
あればどちらを使っても構わない。無能な上司のせいで後で仕様が変わって、中を
いじらなければならなくなるかもしれない。そうでなければstd::priority_queue<>を
使うのが必要十分だろうね。
367 :
360:2005/06/17(金) 02:07:48
>>365-366 むはー。ありがとうございます。
私もなんとなく
>>365さんのように「コンテナを別に持ってそれに演算を加えてたら
余計な計算たくさんしてそう」程度に考えてたのですが、
map(set)も結局コンテナ構造の維持に手間を割いているわけですね。
私の用途だとpriority_queueの方が意味的にあっているので、そちらを使う踏ん切りがつきました。
どうもでしたー。
ヒープは最小(最大)要素の削除はO(log N)が保証されますけれど,
平衡探索木などとは対照的に一般の要素の削除が平均・最悪でO(N)かかります.
一方で空間消費量の点で大きな強みがあり,
最小(最大)要素の削除のみを必要とする,あるいはそれが主たる演算となる
priority queueの実装にヒープが最適な場合が多いというのが通説だったと思います.
369 :
デフォルトの名無しさん:2005/06/17(金) 06:13:18
質問です。
listを使ってるのですが、
class USER
{
public:
int age;
char name[16]
char memo[64];
};
std::list<USER> userlist;
これをUSERのメンバのnameでソートしたい場合どのようにすればいいのでしょうか?
sortを使った場合、入門サイト見る限りはstd::list<int> numlist;のような場合は出来るようですが、個々のメンバに対しては出来ないようなので・・・
また、nameを検索したい場合、algorithmでそのような関数は用意されてますか?
>>369 template<class Compare>
void std::list::sort(Compare comp);
2次元配列を
std::vector<std::vector<float>> matrixA(10)
って感じで作ったけど
for(i=0;i<10;i++)
matrixA[i].resize(20)
って感じで初期化しないといけないよね。
でもこうすると2次元配列がメモリー上でちゃんとならんでくれない
つまり
float *pf=&matrixA[0][0]
としたとき
pf[i*20+j]=matrixA[i][j]
になってくれない。ちゃんとメモリーに並ぶように
2次元配列を作る方法ないのかな
>>371 おとなしく boost::multi_array 使っとけ。
どうせならboost::numerics::ublas の
matrixを使いたい。あれもメモリー上で
きちんと並んでることは保障されてるの?
どうせなら?
用途が全然違うんだが…。
すまない自己解決した
boost::numerics::ublas::c_matrix<10,20>
が目的のものだった。
valarrayってあるけど使ったことないからな。
377 :
360:2005/06/18(土) 21:13:11
>>368 簡潔にまとめて下さってありがとうございます。
378 :
デフォルトの名無しさん:2005/06/19(日) 17:01:22
>>378 ISO/IEC 14882:1998 21.3 Template class basic_string -6
namespace std {
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
class basic_string {
public:
//...
static const size_type npos = -1;
つうかむしろ何が入ってるかは意識しない方がよくね?
384 :
378:2005/06/19(日) 18:18:38
-1で検出無しとしてコーディングしました。
それで問題なくプログラムが動いてます。
ハイ。
MFCのCStringやCArrayからSTLへ移植中です。
>>384 おいおい....
「動けばいいってモンじゃねーだろ」という言葉をプレゼントしておこう
きみ、
EOFもつねに-1と書いて
NULLはつねに0と書いて
Cならプロトタイプ宣言など絶対にせず
nとかiとかいうグローバル変数を定義するタイプか?
>>384 -1使うな。std::string::npos使え。
NULLの場合は常に0と書くのが普通だがな
388 :
384:2005/06/19(日) 18:38:03
-1からnposにしました
nposというメンバがあるんですね。
知りませんでした。
本当に、すいませんでした。
頭悪そうな香具師が一匹いるな。
exit(EXIT_SUCCESS)をexit(0)とか書いちゃう人かな。
俺はEXIT_SUCCESSなんて書かないなあ
失敗がEXIT_FAILUREだけってのも使いものにならんし
>>391 それは同じであることが保証されてるぞ
NULLと違って
>>391 EXIT_SUCCESS なんて使った事がないんだが、それより
() 付けちゃうってのがアレだなあ。
>>395 何でもない。忘れて。吊ってくるから…orz
main()からのreturn EXIT_SUCCESS;かぁ。使わないな。
なまじ演算子に括弧つけなくていいからマクロで置き換えられなかったり
するんだよな。
newとかdeleteとか、全部括弧がついていたら苦労しないのにと思ったことも
あったような希ガス。
std::vector<> の各要素はデフォルト構築ではないのですか?
VC++6,.NET 2003, gcc-3.3.3 でデフォルト構築したテンポラリをコピーしやがりますよ?
#include <iostream>
#include <vector>
class V {
public:
V() : m_v(num++) {print("Constructor"); }
V(const V& v) { m_v = v.m_v; print("CopyConstructor"); }
V& operator=(const V& v) { m_v = v.m_v; print("="); return *this; }
virtual ~V() { print("Destructor"); }
private:
void print(const char* s) { std::cout << s << ":" << m_v << std::endl; }
static int num;
int m_v;
};
int V::num = 0;
int
main()
{
std::vector<V> v(5);
return 0;
}
>>399 これがコンストラクタ。当然そうなるわな。
explicit vector(size_type n, const T& value = T(), const Allocator& = Allocator());
逆に逐一生成した値を入れたい場合だったらどう書きますか?
・ループで push_back()
・back_inserter を使って generate_n()
他、どんなもんでしょ?
vectorクラスで
typedef struct {
char str[512];
} t_str512;
std::vector<t_str512> strings;
という風に固定幅(片方の次元が)の2次元配列を作成するのに、
いつも固定幅の配列の方を定義してるんですが、
便利な方法はありませんか
std::vector<char[256]>のような直感的な書き方がしたいのです。
>>403 固定幅の配列をテンプレートで書けば良い。
std::vector<array<char, 512> > strings;
boost::arrayがまさにそれ。
std::string と std::vector<char> の相互変換で、
string->vector は
std::string s;
std::vector<char> v;
std::copy(s.begin(), s.end(), std::back_inserter(v));
みたいなので出来るかと思うのですが、逆はどうしたら良いのでしょうか。
std::getline() が使えると嬉しいのですが。
>>405 back_inserterはstringにも使えるが。
そもそも、
std::string s;
std::vector<char> v(s.begin(), s.end()); /* string -> vector */
std::string s1(v.begin(), v.end()); /* vector -> string */
で十分じゃないか?
priority_queue に以下のデータを格納したいです
struct myData
{
float key;
Dtata data;
}
格納される順番は myData.key の昇順で並ぶようにしたい。
priority_queueでこんなことできるの?
>>407 keyで比較する関数オブジェクトを比較関数(第三テンプレート引数)に指定するべし。
test
410 :
デフォルトの名無しさん:2005/06/24(金) 22:58:45
>>361 Primer一回立ち読みでもしてみては?
えーとなんで
for (set<X>::iterator it = foo.begin(); it != foo.end(); ++it)
if (it->IsInvalid())
foo.erase(it);
って想定通りの挙動してくれないでしょうか
set<X>::iterator it = foo.begin();
while (it != foo.end()) {
if (it->IsInvalid()) {
if (foo.erase(*it)==0)
++it;
else
it = foo.begin();
}
}
こんなコードしか思いつかなくて泣きそうなんですが…
あ、間違えた
if (it->IsInvalid()) {
foo.erase(it);
it = foo.begin();
}
else
++it;
です
>>411 it = foo.erase(it);
setに限らずSTLコンテナのeraseは削除した要素の次を指すイテレータを返す。
414 :
411:2005/06/25(土) 00:33:30
>>413 Σ(゚д゚lll)ガーン
私の手元の資料だとiteratorを引数にとるeraseの戻り値はvoidで
実際アドバイスどおりのコーディングすると「許されない型」と怒られます…
foo.erase(*it++)
>>411-413 ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130 Defect とされてはいるものの、現行の規格では
AssociativeContainer(set,map,multiset,multimap) の
erase() は void を返すと決められているので
it = foo.erase(it) が動作しない環境のほうが多いんじゃないか?
Effective STL かなんかに載ってたと思うが、
erase() が void であっても動くコードにしとくのが正解だろう。
set<X>::iterator it = foo.begin();
while (it != foo.end()) if (it->IsInvalid()) foo.erase(*it++); else ++it;
417 :
411:2005/06/25(土) 01:06:26
みなさんありがとうございます
簡潔な例にするためにsetで書きましたが
実装はmapでやってたのでこんな不気味な演算子になりました
pool_t::iterator it = m_Pool->begin();
while (it != m_Pool->end())
{
if (it->second.IsAlone())
m_Pool->erase(it++->first);
else
++it;
}
418 :
416:2005/06/25(土) 01:14:49
あれ? foo.erase(*it++) は間違いだな。
>>417 m_Pool->erase(it++) でいいんじゃないか?
わざわざkeyを引数に取るerase呼ばなくても,
iteratorを引数に取るeraseを呼べば良くないですか?
m_Pool->erase(it++);
eraseの内部実装的にも恐らくこちらが速いでしょうし.
ただ,multi(set|map)の場合はkeyを引数に取るeraseと
iteratorを引数に取るeraseで意味が異なるので注意が要りますけれど.
420 :
419:2005/06/25(土) 01:17:00
って先に書かれてました.すいません.
これを見たあなた!!ヾ(・ε・。)
あなたゎこの1ヶ月以内に好きな人と両思い
またゎ付き合っている子ゎすごくLOVE2になります!!
それにゎこの文章をコピーして他の掲示板に3回別の掲示板に
はればOK!!!たったこれだけであなたわぁ
最高の生活がおくれます!!
ただしこれをしなかったら
きっと両思いになることゎないでしょう!!(/□≦、)
やった子ゎ今でゎ学校1のLOVE2カップルです!!
これをやらなかった子ゎすぐに彼氏と別れてしまいました
>>421 好きな人がいません。どうしたら良いですか。
5年生のあいちゃんに片思いなんです。
あいちゃんとLOVE2になれますか?
私は30代独身です。彼女いない暦=年齢です。
>>423 あいちゃんてOOスレに出てくるアンチOOのお猿さんでしょ?
>>423 諦めろ。君の恋愛の対象となった女の子の人生が可愛そうな事になる。
>>411しかり、Effective STL のような本を熟読し、物凄く注意深く使わないとすぐ
予定外の動作をするSTLって、正直ダメなんじゃないか?
STLを使う前からインターフェースだけ見てその罠を全て見抜ける天才なんか存在しないわけだし。
そんなfragileなライブラリってやっぱダメだろ?
>>427 それは、あんたの頭がパーだから。STL向きじゃないので、すぐにC++を
触るのをやめましょう。
429 :
427:2005/06/26(日) 04:12:26
>>428 つまんねーやつ。キミ、アタマ悪いでしょ?
それはある意味、C++そのものを否定するのと同じだな。
>>429 図星を突かれたからと言って、ファビョんなよw
STLのインターフェースがクソなのは間違いない。
>>432 そう思うんならC++標準委員会で発言してみろ。
できない癖に偉そうな口聞くんじゃない。
自作のステキライブラリでも使ってればいいのに
, -'"´  ̄`丶、_
,.∩ `ヽ
〃∪'´ ̄`二二人\ ヽ
| ツ´ ̄ ̄ ̄ ̄´ ヾ ヽ. ',
|ハ ,ニ、 ,. - 、 | | | l |
| ハ ィハ ,二ヽ. | | | | | 同じ板にコピペするとそのままだけど、
| | | じ' |トJ〉 /)} l | 違う板にコピペすると鬼のような怖い顔
| ハ 、'_,  ̄,, 厶イ川| に変わる摩訶不思議な佳子様コピペ。
l l /\ .. イV\川 |
,' l l ,イ `l ̄´ / /ヽl l
l | l ハ `メ、 〃 ヽヽ、__ノ
l ∨ └‐イ「ト--ァ'´ ハヽ__ノ
ヽ/ } l」」 / / }`ー
〈_n| 八 / / /ノ
〈二二人 c /\/ / , イ
/ /厂 /\__>< {_
437 :
436:2005/06/26(日) 21:50:10
なんだよ!
全然かわんねーじゃん!!
騙された・・・orz
C++は「泥にまみれた現実を通り抜ける」ために
「一部の馬鹿を冷徹に置き捨てることを厭わない」言語だからねえ。
どうしても、肯定派の会話は戦略会議的に、否定派の会話はしゃべり場的に
なっちゃうね。
.┌━┐ ┌━┐
┃┌╋──╋┐┃
└╋┘ └╋┘
┃ ・ ・ ┃ ┌━━┐
●━╋┐ ┌╂━━━━╂┐ ┃
└━┷┴━━╂┘ └╋━┘
┌╋┐ ┌╋┐
バカには出来ない ┃└╋╋━━╋╋┘┃
C++です ┃ ┃┃ ┃┃ ┃
┃ ┃┃ ┃┃ ┃
└━┘┘ └└━┘
>>427-439 C++ならではのバグに悩まされて泣き言言っている連中がよく言うぜw
笑わせるな凡人風情がw キミたちの為にJavaはある。
boostとSTLを駆使して作ったプログラムを携帯で動かすには
Javaで書き直すしかないのかな
BREWでもboostやSTLは動かんだろ。
boostとSTLを駆使して作ったプログラムを携帯で動かすには、
ARM C++用に、boostとSTLを自分で書く。
javaにはboostに対応するものはないの?
>>447 "Go ahead and use the STL" と書いてあるのが見えないのか?
そのまま使うな
カスタムアロケータを使えと書いてある
そういやBREWのメモリ割り当てって
なんか凄い間抜けな仕様だと聞いた事がある。
boost::multi_array よりも
vigra::MultiArray
のほうが機能が充実してて使いやすい気がするんだけど
俺だけ?
>>454 vigraは画像処理がメインのターゲットだけど
vigra::MultiArray は一般的に使える
例えば行列演算のvigra::Matrixは
vigra::MultiArrayの特殊化
数値計算関係はboostは充実してないって結論に達したけど
反論求む
boostの行列演算
boost::numerics::ublas::matrix
は、ublas::matrixViewクラスがないので使いにくい
boost::numerics::ublas::matrixは
boost::multi_arrayの派生クラスになってないよね?
ここはSTLのすれなんだが。
でもtemplateスレは別に在るわけで。
そもそも相談室であって雑談スレではない
「反論求む」とかバカじゃねえの?
C++ スレの
>>1 がやっと直ったんで
このスレは要らなくなったわけだが。
std::stringstreamの中身を捨てて初めからやり直したい時ってss.str("");でいいんですか?
(ssはstringstreamの変数名としてます)
ss.flush(); とか ss << std::flush; とか何も起こらないみたいですがどうなってるんでしょうか?
>>461 ss.str(""); でいい。
flush()は、std::stringstreamがデバイスに連結されている訳ではないので、
何も起きない。継承上の残骸と思えばいい。
>>462 そうだったんですか。
どうもありがとうございます!
>>455 >boostの行列演算
>boost::numerics::ublas::matrix
>は、ublas::matrixViewクラスがないので使いにくい
matrixView ってどんなクラス?意味がわからん。
ExpressionTemplate なら実装されてるが。
>boost::numerics::ublas::matrixは
>boost::multi_arrayの派生クラスになってないよね?
派生クラスである必要は全くないし、
派生クラスだったらむしろ困る。
メモリの並び方とか指定できないじゃん。
STL始めたばかりの初心者です。
void insertion(list<string> & a, int l, int r)
{int i, j;
for(i=l+1; i<=r; i++)
{
string temp = a[i];
j = i;
while((j>l) && (temp < a[j-1]))
{
a[j]=a[j-1];
j--;
}
a[j] = temp;
}
}
上記の挿入ソートにリストを受け渡そうとしていたのですがvectorやdequeのように ls[] とするとエラーになってしまいます。
list<string> ls;
ls.push_back("c");
ls.push_back("a");
ls.push_back("b");
insertion(ls, 0, ls.size()-1);
そこで、list<string>::iterator it = ls.begin();などとして、なんとかリストの受け渡しをしようと試行錯誤してみたのですがうまくいきません、大変お手数ですが、何かアドバイスなどございましたら、お聞かせいただけないでしょうか。
>>466 listはランダムアクセス出来ないから無理。
対処としてはsetを使う。
>>466 listを渡すのではなく、iteratorを二つ渡せば?
んで、operator[]を使わずにiteratorを++すると。
#つーか、std::sort()の実装でも見てみたら?
お返事ありがとうございます。
>>467 さま
setをどのように利用すればよろしいでしょうか。
>> 468 さま
iterator を2つといいますと、ls.begin();に対して2つ設定するということでしょうか。
大変申し訳ございませんが、再度ご教授お願いします。今からsetおよびstd::sort
()に関して調べてきます。
operator[]が使えなくとも、ほとんどのソートアルゴリズムは使える。
但し、O記法で、本来のオーダーが出なくなってしまう物があるので、
そういうのはSTLには入っていない。
>>469 set について調べれば使い方がわかるだろう。
sort について調べれば「iteratorを二つ」の意味がわかるだろう。
質問は自分で調べてからにしような。
472 :
468:2005/07/04(月) 12:03:32
教授する気はないので勝手に調べてくれ。
それでも分からなければ教示しないでもないが。
奴隷に噛み付かれたと思ってむかついた466がそろそろ
調べることを頑張らないまま皮肉を頑張りに来るぞ。
ID導入反対
テストしてない、よく考えてないが、たとえば↓
string限定という糞ぶり、こんなの書いてきたらグーパンチだろうが、何かの参考にどうぞ
template <typename BidirectionalIterator>
void insertion(BidirectionalIterator first, BidirectionalIterator last) {
for (BidirectionalIterator i = ++first; i != last; ++i) {
string temp = *i;
BidirectionalIterator j = i, current = j;
while ((current = j) != first) *current = *(--j);
*current = temp;
}
};
list<string> ls;
insertion(ls.begin(), ls.end());
mapやmultimapのイテレータは、要素の追加などを行っても使えるのでしょうか?
それともvectorのように再配置が起きて使えなくなる、といったことがあるのでしょうか?
>>477 問題ない。
23.1.2の8
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.
479 :
デフォルトの名無しさん:2005/07/06(水) 21:30:26
トリビアC++
480 :
デフォルトの名無しさん:2005/07/06(水) 22:56:14
.net2003のVCでSTLのコードがコンパイル通らないので
STLport(4.6.2)をmakeしてインストールしたら
コンパイルは通るようになったが、リンクでlibc(d).libと
バッティングしてしまいました。
lb_test error LNK2005: ____lc_codepage_func は既に LIBCD.lib(initctyp.obj) で定義されています。
なかんじで。対処法ご存知でしたら教えていただけないでしょうか?
>>479 Tribial C++とか言う本がありそうだな。
482 :
481:2005/07/06(水) 23:21:25
Trivialだった。恥ずかす
×.net2003のVCでSTLのコードがコンパイル通らないので
○.net2003のVCでSTLを使った初心者丸出しコードがコンパイル通らないので
stl::vector<T>の代わりにstl::vector<T*>を使うことはよくあると思うのですが、
const文脈においてdereference演算子の返り値をT * constではなくconst T*にする、
あるいはbegin(), end()の返り値をstl::vector<T*>::const_iteratorではなく
stl::vector<const T*>::iteratorにする、あるいはコピーコンストラクタで
引数stl::vector<T*>を受けてstl::vector<const T*>(ライクな型)に変換する
お約束の方法などはあるのでしょうか?
boostのiterator_adaptorsが多分目的に適っているのですが、
自前で簡潔に書けるのであればなるべくそうしたいのです。
>>485 C++ではconst属性に対する抜け道もちゃんと用意されている。
const_cast<T*>(p);
vector<T*> nonconst_vec;
vector<const T*> const_vec(nonconst_vec.begin(), nonconst_vec.end());
488 :
485:2005/07/07(木) 18:22:17
>>486, 487
どうもありがとう。
>>486 std::vector<const T*>::const_iterator
begin(void) const { return std::vector<const T*>::const_iterator(const_cast<const T**>(&*m_vector.begin())); }
これでうまくいくのを確認したのですが、こんなもんでしょうか?
スマートでなければ指摘して頂けるとありがたいです。
>>487 イテレータを渡すのですね。どうもです。
489 :
485:2005/07/07(木) 18:46:47
よく考えると、
>>488だとconst_castを使わずに
std::vector<const T*>::const_iterator
begin(void) const { return std::vector<const T*>::const_iterator((T**)(&*m_vector.begin())); }
としてもよいのですね…。
490 :
480:2005/07/07(木) 20:19:29
>>484 解決しました。ありがとございます。
LinuxとWindowsのマルチプラットフォームなもので…。
>>488 T** から vector<T*>::const_iterator は変換 construct できるとは限らないのでは?
>>488-489 実装依存でいいならあとはコンパイルさえ通れば大丈夫だろうけど、
規格上 std::vector<const T*>::const_iterator が const T** で初期化できるなどという保証は無い。
さらに、たとえポインタの指す先の const が違うだけでも、
要素型の違う std::vector の間で iterator を相互変換できる保証も無い。
class vector_485
{
std::vector<T*> m_vector;
↑こんな感じで標準コンテナに準拠したラッパーを作るって話なら
iterator 型をポインタの typedef にすれば実装できそう。
>>492 コンパイルが通って、なおかつその処理系のドキュメントが
期待する動作を保証しているならば、ね。
494 :
デフォルトの名無しさん:2005/07/08(金) 01:17:06
stlportでstl::stringのコンストラクタにNULLを渡すと
エラーになるんですが、これって標準なんですか?
'\0'も一応文字だと思うんですが、なぜエラーに・・
>>494 basic_string<char>::basic_string(char);
こういうコンストラクタがないからじゃないか?
>>494 '\0' は文字と言えるが、 NULL は断じて文字ではない。
std::string s(1, NULL) ってやるなよ。
499 :
485:2005/07/08(金) 01:59:10
>>491-493 ありがとうございます。
> 要素型の違う std::vector の間で iterator を相互変換できる保証も無い。
まさにここを解決したかったわけですが、うまい方法はないようですね。
>>492の方法も試してみます。書いてみて格好悪かったら…とりあえず
>>489でいきます。
> 規格上 std::vector<const T*>::const_iterator が const T** で初期化できるなどという保証は無い。
重々承知ですm_ _m
でもvectorのiteratorをポインタで初期化できない実装って存在するのでしょうか?
ただの興味ですが。
>>499 > でもvectorのiteratorをポインタで初期化できない実装って存在するのでしょうか?
#include <vector>
std::vector<int>::iterator x(int* p) { return p; }
$ g++ -fsyntax-only
: In function `__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > > x(int*)':
:2: error: conversion from `int*' to non-scalar type `__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >' requested
>>499 Metrowerks CodeWarrior for Windows v8.3
エラー: 'int *'から'std::__wrap_iterator<std::vector<int, std::allocator<int>>, int *>'への
不当な暗黙の変換です。
502 :
デフォルトの名無しさん:2005/07/08(金) 05:56:17
>>495-498 std::string str( '\0' );
とやっても不正アクセス例外になりますよ・・
長さゼロのstd::stringインスタンスが存在できるということは
内部的に長さゼロの文字列は('\0')を持つことと同義ですよね。
うー納得いかねえ
>>502 だからそういうコンストラクタはないっつーに。
std::string str(""); ならわかるが。
>>503 うわーやっとわかりました。
いままで'\0'と"\0"の違いがわかってなかったです。
ありがとう君。
0とNULLと'\0'と""の違いをSTLスレでやるなよな……。
""と"\0"にも違いがある
507 :
485:2005/07/08(金) 10:39:28
>>500 #include <vector>
std::vector<int>::iterator x(int* p) { return std::vector<int>::iterator(p); }
で通りますが…。
508 :
485:2005/07/08(金) 10:41:48
連続すみません。
>>501を見落としてました。CodeWarriorでは駄目ですか。
>>507のようにしても駄目でしょうか。
>>507 フーン
#include <vector>
std::vector<int>::iterator x(int* p) { return std::vector<int>::iterator(p); }
$ g++ -D_GLIBCXX_DEBUG -fsyntax-only
: In function `__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<int*,
__gnu_norm::vector<int, std::allocator<int> > >, __gnu_debug_def::vector<int, std::allocator<int> > > x(int*)':
:2: error: no matching function for call to `__gnu_debug::_Safe_iterator<
__gnu_cxx::__normal_iterator<int*, __gnu_norm::vector<int, std::allocator<int> > >,
__gnu_debug_def::vector<int, std::allocator<int> > >::_Safe_iterator(int*&)'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/debug/safe_iterator.h:122: (略
ミクロなことで勝ち誇るなよw
511 :
485:2005/07/08(金) 15:43:43
>>509 おぉ。ありがとうございます。
手元のg++(3.3.1)ではg++ -D_GLIBCXX_DEBUG -fsyntax-onlyで通りますが、
3.4.4では駄目なのですね。
512 :
485:2005/07/08(金) 15:55:56
というか、_D_GLIBCXX_DUBUGってg++(3.4)からなのですね。
知らないことだらけだ…。スレ違いご容赦。
>>508 普通にコンパイルすると恥ずかしながら通った。#define _MSL_DEBUGすると
通らない。
エラー: 関数呼び出し '[std::__debug_iterator<std::vector<int, std::allocator<int>>, int *, 0>].__debug_iterator({lval} int *)' が一致しません。
std::__debug_iterator<std::vector<int, std::allocator<int>>, int *, 0>::__debug_iterator()'
'std::__debug_iterator<std::vector<int, std::allocator<int>>, int *, 0>::__debug_iterator(const std::__debug_iterator<std::vector<int, std::allocator<int>>, int *, 0> &)'
'std::__debug_iterator<std::vector<int, std::allocator<int>>, int *, 0>::__debug_iterator<...>(const std::__debug_iterator<std::vector<int, std::allocator<int>>, __T1_0, 0> &)'
'std::__debug_iterator<std::vector<int, std::allocator<int>>, int *, 0>::__debug_iterator(const std::vector<int, std::allocator<int>> *, int *const &)'
main.cpp 行: 4 std::vector<int>::iterator x(int* p) {return std::vector<int>::iterator(p);}
VC7.1 付属 STL の vector って、
vector<bool> 以外は clear するとメモリを開放するんですね。
意外でした。
516 :
デフォルトの名無しさん:2005/07/10(日) 08:16:17
配列の積和を行うinner_productというのがありますが
3つ以上コンテナの積和をSTLを使ってエレガントに実現
する方法はありませんか?
予定では3つから7つ程度のコンテナの積和が必要になり
ますが、できればSTLで実現したいと思っています。
以下自作コードです。
---------------------
template<class Iter1, class Iter2, class Iter3, class T>
T inner_product3( Iter1 f1, Iter1 l1, Iter2 f2, Iter3 f3, T init )
{
for( ; f1 != l1; f1++,f2++,f3++ )
init = init + ( *f1 * *f2 * *f3 );
return init;
}
#include<iostream>
void main()
{
int a[] = {1,2,3,4,5};
int b[] = {1,2,3,4,5};
int c[] = {1,2,3,4,5};
int sum = inner_product3( a, a+5, b, c, 0 );
std::cout << "sum=" << sum << std::endl;
}
こんばんわ
文字列検索の案件をしてるんですが、
std::stringでfindを呼び出し解析をしてましたが、
ためしに、CString(MFC)に変えてFind検索をしたら
劇的に早くなりました。
その辺どうなのでしょうか?
開発環境はVCです。
これは単にSTLが重いということでよろしいのでしょうか?
知らず知らずの内に一時オブジェクトを生成してる悪寒
519 :
517:2005/07/10(日) 13:05:27
今、アプリケーションを、std::stringからMFCのCStringベースに変えました。
思わず笑っちゃいました。
あまりの処理速度の違いにですw
もちろんMFCのほうが速いんですが。
時間を計測したら50倍ほど早く処理できてますね。
アルゴリズムには問題はないと思ってましたので、
どうしてこんなに重いのかと悩んでたら、
癌はSTLでした。
STLを使うのはやめようと思います。
>>519 あーはいはいそれはよかったね。
ここはお前の日記じゃないから。チラシの裏にでも書いてろ。
>>519 ついでに書くと、std::stringはSTLじゃないから。馬鹿ですねー
>>516 あんまりきれいじゃないけど
template<class Iter1, class Iter2, class Iter3, class T>
T inner_product( Iter1 f1, Iter1 l1, Iter2 f2, Iter3 f3, T init )
{
vector <T> tmp (distance (f1, l1));
transform ( f1, l1, f2, tmp.begin (), multiplies <T> () );
transform ( tmp.begin (), tmp.end (), f3, tmp.begin (), multiplies <T> () );
return accumulate ( tmp.begin (), tmp.end (), init );
}
>>519 速度にこだわるならstrstrのほうがCString::Findより3倍近く高速ですよ( ´∀`)
>>523 strstrの逆検索バージョンはあるのでしょうか?
部分文字列検索だけなら、自分でB&M法でも使って組んだ方が
ずっと速いだろうに。
527 :
522:2005/07/10(日) 13:58:17
書いてみたけど
コンテナ増えたらIteratorでなめる回数が増えて遅くなりそうだ
たぶん516の方がマシですね
忘れて
>>527 STLは、標準化の際に大幅に内容を削除されたからね。
元々3D用のinner_product3D() なんてアルゴリズムもあったのかもしれない。
>>517,519 最適化されてないんじゃないの?
>>517 VCについてくるSTLはあまりできがよくない。
STLPortを使うべきだろう。
コンパイラオプションによるんじゃないの?
50倍っていうくらいだから
何か根本的なところで間違っている気がする
たとえ50倍遅かったとして、それほど処理時間に差が出るものなのか
>>534 50倍とか言われると流石に気になるだろ
給料50倍なら、2年働けば生涯年収越えちゃうんだぜ
std::stringよりMFCのCStringの方が早いというのは事実とは思うんだけど、
MFCって今後どうなっちゃうんだろう?
どういう操作が遅いのかが全然わからんが、
察するに、参照カウント使って
共有してるかどうかの差が出たんじゃないか?
文字列検索って深いテーマだと思うぞ。
簡単そうに見えるが。
for_eachにかけるfunctorの中でとなりの隣のiteratorにアクセスできるの?
struc functor
{
operator()(Iterator it)
{
return (it+1)
}
}
>>540 Input Iterator なら隣に行ったらもう戻れない
Forward Iterator なら問題なし
it + 1 なんて書き方ができるのは Random Access Iterator
for_eachに渡すfunctorってIterator受け取らないよね。
じゃあリストの前後3要素の平均求めたい場合は
functorは使えないんだね
operator()( 今いるとこ)
{
return (前 + 今いるとこ + 後)/3;
}
>>544 Bidirectional Iterator(--と++ができるイテレータ)を取ればできるんじゃ。
std::listは双方向リストなので、Bidirectional Iteratorが使える。
ただし、現実的には、過去2つの値をメンバ変数に保存しておいて、
現在の値との平均を返した方がよさそう。
// functorを使うということは、iterativeなアルゴリズムだろうから
struct funct0 : public std::unary_function< void, int >
{
int* average;
int index;
funct0( int* average_ ) : average(average_), index(0){}
result_type operator ()( argument_type arg ) const
{
average[index++] += arg;
}
};
struct funct1 : public std::unary_function< void, int >
{
int* average;
int index;
funct1( int* average_ ) : average(average_), index(0){}
result_type operator ()( argument_type arg ) const
{
average[index] += arg;
average[index++] /= 3;
}
};
void f()
{
std::vector<int> srcarr:
std::vector<int> average( arcarr.size() - 2, 0);
for_each( srcarr.begin() + 0, srcarr.end() - 2; func0(average));
for_each( srcarr.begin() + 1, srcarr.end() - 1; func0(average));
for_each( srcarr.begin() + 2, srcarr.end() - 0; func1(average));
}
流石に無理あるな。
つーか間違いまくりorz
549 :
543:2005/07/11(月) 20:51:29
>>544 こういうことがしたいの?
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
int main() {
using namespace std;
int a[] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15,};
int size = sizeof(a)/sizeof(a[0]);
vector<int> v;
transform(a, a + size - 1, a + 1, back_inserter(v), plus<int>());
transform(a, a + size - 1, v.begin() + 1, v.begin(), plus<int>());
transform(v.begin(), v.end() - 1, ostream_iterator<int>(cout, "\n"), bind2nd(divides<int>(), 3));
}
550 :
デフォルトの名無しさん:2005/07/11(月) 21:07:06
vector<Class*> v
このvの中のいくつかがヌルポインターなんだけど、どうやって消したらいいの?
551 :
デフォルトの名無しさん:2005/07/11(月) 21:13:09
std::erase(std::remove(v.begin(), v.end(), static_cast<Class*>(0)), v.end());
552 :
550:2005/07/11(月) 21:18:35
>>551
ありがとうございます。
せっかくだからもうちょっとわかり易く教えていただけますか?
>>552 std::remove()は3つ目の引数に一致する要素を探し、それを列の後ろへ集める。
そしてその集めた部分の先頭の位置を返し、そこからend()までは今回ヌルポインタの要素が集まっている。
そこをerase()で削除すればいいというわけ。
554 :
550:2005/07/11(月) 21:48:14
>>553 なんで2回も消しているのかわかったかもしれない。ちょっと試してみる。
ヒント : std::remove()は並べ替えをするだけで削除は行わない。
removeて名前付けに失敗してるよな
な?
そうかな。
俺はstlの「シーケンスを変更するアルゴリズム」はそういうものだと理解すべきだと思うが。
remove_copyとの対称性もあるし。
>>558 計算機世界の語感的にremoveは削除の意味で使われるケースが多いと思うので(辞書的には「移動」だけど)
(remove_copyも含めて)やっぱりわかりにくいと思います。
move_backwardとかの方がベタでわかりやすい…。
ダイエットにいいらしい。
> 計算機世界の語感的にremoveは削除の意味で使われるケースが多いと思うので(辞書的には「移動」だけど)
??????
思わず辞書引いちまったじゃないかモルァ
std::remove の動作って一言でズバっと言い表せないんだよな
要らん物を除いて要素を前に詰めてって新しい最後尾の位置を返す
・・・長いな。
除く・詰める・最後尾を返す、の3点はどれも、省くと片手落ちの説明になるしなぁ。
>>559 いや、俺は「削除」で良いと思う。
stlのアルゴリズムで要素を削除するというのは、それを後ろに移動して、
境目のイテレータを返すことに他ならない。
標準ライブラリなんだから、そういう知識を利用者に要求してでも
名前を簡潔にすることは正しい選択だと思う。
それに、こうやって理解しないと、removeとremove_copyを統一的に把握できない。
uniqueとunique_copyについても同様。
>>553>>559>>565 君たちは根本的に勘違いしているj。
{1,0,5,7,0,6,4,0,4,8,3}
↓remove(..., 0);
{1,5,7,6,4,4,8,3,4,8,3}
ここを指すiteratorを返す
後ろに移動はしない。移動させる変な処理系もあるかもしれないが、それは定められた操作ではない。
>>565 std::list::removeの動作はまた違うわけだが…
>>551 v.erase……
>>566 まあその通りやね。
std::remove()の動作は、「削除した要素」は、「削除されなかった要素で
上書きされる」だから。
569 :
559:2005/07/12(火) 20:45:16
>>566 なるほどっ。
「除外するけど除外されたやつのことは知らん」という感じですか。
exclude
>>567 確かにコンテナのサイズを変えるような処理はメンバ関数じゃナイトで金罠
>>569 うん、だからヒープオブジェクトへの頭の悪いポインタのコンテナに対して
迂闊にremoveやuniqueを使うとメモリリークする
STLのコンテナってAllocator指定できんのにDeallocator指定できやんの?
Allocator が deallocate もする
>>572 アロケータのメンバ関数allocate()、deallocate()について調べてみ。
MFCが50倍速い
っていうのがいまだに引っかかる
boostのホームページには
abstruction のコストは2倍ぐらいって
書いてあったんだけど
50倍って本当?
>>575 たぶんdebug版でbuildして遅いとか言ってるんじゃないの?
もしdebug版を使っていたとすると、関数がinline化されなくて遅くなるから、それでSTLが癌と勘違いしたのでは。
俺はこの可能性が一番高いと思う。
まぁ単純にCStringが物凄い速い可能性もあるけど、さすがに50倍は無いと思う。
速度を計測してないから自信は無いけど。
具体的に50倍の速度が生じるコード片を提示してもらわないことには何とも言えんわな
>>576 あとは、CString 同士の Find() は最近の結果をキャッシュしているとかかな。
MFC は触ったことさえないが。
579 :
デフォルトの名無しさん:2005/07/13(水) 23:59:38
つか、stringとかは、ヘッダ見れば大体のコスト分かるだろ。
まあ、50倍ってのは無知が適当に書いただけにしか見えんが。
コンパイラが最適化したんじゃないの?、const文字列扱いで。
はい、噂だけが先行してますね〜
583 :
デフォルトの名無しさん:2005/07/15(金) 03:49:04
stringからwstringに変換したいのですがうまくいきません. STLport4.6.1です
using namespace std;
wcout.imbue(locale("japanese"));
mbstate_t state = mbstate_t();
string in("波浪ワールド");
wstring out(in.size(),L'.');
cout << "Before:" << endl;
cout << in << endl;
wcout << out << endl << endl;
string::iterator in_it = in.begin();
wstring::iterator out_it = out.begin();
locale loc("japanese");
const codecvt<wchar_t,char,mbstate_t>& cdcvt = use_facet<codecvt<wchar_t, char, mbstate_t> >(loc);
cdcvt.in( state, in.begin(), in.end(), in_it, out.begin(), out.end(), out_it);
cout << "After:" << endl;
cout << in << endl;
wcout << out << endl;
>>583 STLportにはstd::locale("japanese")なんか実装されてなかった希ガス。
585 :
デフォルトの名無しさん:2005/07/15(金) 11:08:27
私の記憶が確かならば、STLport の codecvt ってか、ctype.widen は、
単に1文字ごとに static_cast< wchar_t > してただけだったような気がする。
STLPortになければ自分でfacet書いてlocaleにブチ込めばよいじゃない
結局、オープンソースはそうなっちゃうのよね>他力本願
金もらわずに半ば趣味で作ってる人がほとんどだから、
「規格はこちらで決めるから、後はwchar_t関連などは、それぞれの国で
実装してちょ」って感じなんでしょ。ほとんどが7bit圏の人ばかりだったり、
そうでなくても7bitで我慢している人がほとんどだろう。
日本なんかはまだ恵まれている方。
588 :
583:2005/07/15(金) 18:27:07
locale loc("american");
const codecvt<wchar_t,char,mbstate_t>& cdcvt =
use_facet<codecvt<wchar_t, char, mbstate_t> >(loc);
で成功しました.
stringのiteratorを渡せるのはreleaseモードの場合だけでした
c_locale_win32.cでMultiByteToWideCharを呼び出していました
>>588 なんじゃそりゃ
localeの設定に関係なく、MultiByteToWideChar()で結局ACP依存の変換やっとるのか
バグっつーか腐ってるな
>>590 バグでしょ。あきらかに。
>>588のコードで
CP932からUnicodeへの変換が行われるのが仕様通りだとでも?
手で抜いてください。
VC7.1のstd::char_traitsのcopyやmoveって間違ってないか?
FromとToの関係が逆なような希ガス
copy(_Elem *_First1, const _Elem *_First2, size_t _Count)
において、_First2 → _First1 の方向にコピってるようだが...
まぁconstにはコピーできんわな
>>595 そりゃそうだな。でもコメントには
// copy [_First1, _First1 + _Count) to [_First2, ...)
って書いてあるし、ヘルプにもそうある(゚Д゚)
598 :
デフォルトの名無しさん:2005/07/16(土) 00:55:14
class A{
public:
void scr(){
std::cout << "A!" << std::endl;
};
};
int main(){
std::vector<A> AV;
AV[8798].scr();
return 0;
}
結果:
A!
釈然としないんですが、規格上こうなんですか?
>>598 偶然。
ってかA::scr()がAのプロパティに触らないからアクセス違反が起きないだけ。
メソッド呼び出しよりAV[8798]の方が問題
いや、だから、何でそれでエラーが起きないかって話しなんだが。
602 :
598:2005/07/16(土) 01:41:01
>>599 いや、まあそうなんですけど
スルーしちゃうのはどうかなと
vectorの速度を落とすようなチェックは要らんということでしょうか
603 :
598:2005/07/16(土) 01:42:46
とりあえず偶然ということで納得しました
ありがとうございます。
>>602 そこにチェックが入って速度落とされちゃたまらないからね。
標準ライブラリの実装によっては、デバッグモードを使えば安心できるかもしれない。
operator[]()はチェックなし。
at()はチェックする(範囲外は例外を投げる)。
使い分けできるようになってんだよ。
マイクロソフトはなんでSTLのiostreamとstring,wstringなどをある程度扱うDLLを
Windows標準添付にしないのか、なぜもっとc++をプッシュしないのか?
>>606 msvcpXX.dllならWin98のあたりから標準搭載だけど。
>>606 >STLのiostreamとstring,wstringなどを
帰れ。
610 :
デフォルトの名無しさん:2005/07/16(土) 11:11:48
配列の中に、ベクタを作成したいのだけどどうすればいいのでしょうか?
ベクタ型の配列
[0] vector<int> 〜
[1] vector<int> 〜
[2] vector<int> 〜
[3] vector<int> 〜
vector<int> v[n];
でできました。すみません。
vector<vector<int> > v;
のほうがいいんじゃない?
>>612 元のほうは可変の必要が無いので大丈夫です。有難う御座います。
598って、偶然なの?
仕様どおりな希ガス
char a[10];
printf("%p", a + 4096);
は未定義ということでいいのかな?
参照剥がししない限り、こういうコードは問題なく動く処理系が
多いとは思うけれど。
未定義。
a+10までは大丈夫だけど
ただし*(a+10)は未定義
でも&*(a+10)は大丈夫
>>618 >>616はどこも参照剥がし
*(a+10)
をしていないと思うんだが。
ついでにいえば、
>>598も、thisポインタは必要だが
参照剥がしはしないから動くんだと思うんだが。
621 :
618:2005/07/16(土) 21:09:20
>>616が参照剥がしをしている
なんて一言も言ってないが。
関係ないが
>>598はscr()定義の直後にある無駄なセミコロンが気になる
std::stringにフォーマット出力はないんか?
operator[] が例外を投げないとは限らない
at と同じ実装である可能性もある
>>621 じゃあ、一行目の「未定義」ってのは、何が未定義だと言ってるんだ
>>624 operator[]が例外を投げるのなら、未定義動作にはならないと思う
627 :
624:2005/07/16(土) 21:18:05
おれは
>>598 の結果が仕様どおりではないと言いたいだけ。
未定義云々の話はしてない。
もしかして
>>621って聞かれてもいないことについて、勝手に自分で
例を作ってそれを未定義だと言ってるだけ?
アフォじゃないの?
>>616の
...は未定義ということでいいのかな?
を受けて、言ってるんだが。
読解力無いのか?
>>629 で、参照剥がしはしていないんだが、なんで未定義なの?
あーごめん
>>618は「最後の一個後の要素」の扱いについて、親切に解説を加えてある
だけなのね。
誤読してたわ。
つまり、AV[0].scr(); ならば、規格どおりとそういうことか?
>>632 AV.empty() なので AV[0] も規格に従い未定義動作です。
class A{
public:
static void scr(){
std::cout << "A!" << std::endl;
};
};
int main(){
std::vector<A> AV;
AV[8798].scr();
return 0;
}
これなら規格通りだろ?
>>634 それだとAV[8798]を評価せずともscr()を呼び出せるけど
AV[8798]を評価するならば、その時点で未定義になるんじゃないの
>>635 「規格通り」って何が言いたいんだ?
とりあえず、そのコードが未定義動作を引き起こしても規格通りだよ。
637 :
636:2005/07/16(土) 22:01:28
アンカーミスった。 >636 は
>>634 宛て。
>>623 printf/scanfがcout/cinになったように<sstream>に<<と>>で入出力するstringstreamがある。
C/C++なんでも質問スレはここですか?
>>634 staticメンバ関数呼び出し時のメンバアクセス演算子の左辺は常に評価される。
>>634 VC7.1+STLportで追いかけてみたけど、operator[]で、AV[8798]
のアドレスを計算していたけど、その後のメンバ関数コールは静的に
解決されていて、折角計算したアドレスは使用してなかった。
これが仮想関数だったりすると、動的解決なので、まずクラッシュ
するだろうな。
>>642 へえ、最適化してもわざわざAV[8798]評価してるんだ。意味無いのに。
それともデバッグ版のコードの話?
>>643 STLportのデバッグじゃないけど、VCのデバッグで最適化無しのコード。
最適化したら、コード通りにバイナリ吐いてくれない事があるから。
これならやっぱりクラッシュした。
class A {
public:
virtual void scr() {
std::cout << "A!" << std::endl;
}
};
int main()
{
std::vector<A*> AV;
AV[8798]->scr();
}
>>644 最適化無しなら、評価してる限りコードが出るのは当然だな。
って、オマエ、コード通りのバイナリ吐く最適化なんて意味無いじゃん。
最適化の意味わかってんのか?
>>646 お前の噛み付き方だけが意味不明だぞ。
ちょっと落ち着けよ。
>>646 何でも噛みつけばいいってもんじゃないよ、知ったかぶりさん。
>>646 落ち着けっ!
落ちぼああああああ着がはぁあああああああああああ!!
結構ひっぱるなぁ みんな。なかなかオチがつかない・・・
ごめんなさい、ごめんなさい、ごめんなさい、暑さで脳をやられてます。
>>646のプロジェクトがデスマ中のようです
ω・`)っ旦旦 冷えた麦茶ドゾー
654 :
デフォルトの名無しさん:2005/07/20(水) 01:13:38
template<calss T>
void func()
{
vector<T> ve;
vector<T>::iterator itrt = ve.begin(); *
}
*でコンパイルエラーが出るのですが、どのように記述すればいいのでしょうか?
>>654 class Tとか。std::vectorとか。typename vector<T>::iteratorとか
657 :
デフォルトの名無しさん:2005/07/20(水) 19:34:03
>>10 Visual Studio .NET 2003を使っています。
STLを使おうかと思ってるのですが、VS2003のSTLも糞ですか?
SGIやSTLPort版を使うべきですか?
エロイ人教えて!
先ずは使ってみよ。
VC 7.1はDinkumwareじゃなかったっけ?
ソースのなかにP.J. Plaugerという署名がポロポロ……
>>660 ポロポロがボロボロに読めて吹き出してしまったよ
Visual StudioのSTLを悪く言う人がいるけど
STLPortとくらべて具体的にどこがどう悪いのか指摘してくれないかな。
昔は確かに問題が多かったけど最近はよくなってきてると思うけど。
>>662 それは逆に君が
VCSTLが以前と比べどのように改善したのか
述べてくれるといいと思うよ。
関数ポインタをvectorにしたいのですが、具体的な記述がよくわかりません。
vector<void (__cdecl *)()> pf;
これではエラーでした。
どうすればいいのでしょうか?
うちはこんな感じで通ったけど。
void
foo()
{
cout << "hello, world" << endl;
}
int
main()
{
vector<void(*)()> pf;
pf.push_back(&foo);
(*pf.begin()) ();
return 0;
}
>>665 ありがとうございます。
以下でやったら通りました。ありがとうございました。
void f::f1(){
AfxMessageBox("f2");
}
void f::fmain()
{
vector<void (*)()> pf;
pf.push_back(&f::f1);
}
>>666 そのf::f1へのポインタ型はvoid (*)()だけど、
もしstaticじゃなければその関数へのポインタ型はvoid (f::*)()になる。
もちろんfがクラスだとしての話。
>>667 すみませんstaticじゃ無いほうがいいんでアドバイスどおり
void (f::*)()
とやったんですが、以下の部分でコンパイルが通りません。
(*pf.begin()) ();
>>669 インスタンスが無いんじゃないの?
↓
pf.push_back(&f::f1);
f F;
(F.**pf.begin())();
>>670 メンバ関数の中でそのメンバの関数ポインタを呼んでるので、
インスタンスは呼ばなくていいんじゃないのですか?
error C2171: '*' : オペランドが不正です。
というエラーになります。
>>669 void f::fmain()
{
vector<void (f::*)()> pf;
pf.push_back(&f::f1);
(this->*pf.front())(); //(this->*(*pf.begin()))()相当
}
.*と->*はそれぞれ1つの演算子で、.や->と*には分けられないからthisを補う必要がある。
pf.front()は先頭要素を返すから*pf.begin()相当。
673 :
670:2005/07/21(木) 22:15:06
>>671 あ、しつれい。f::mainなのね。
>>672氏の通りで、どのみちインスタンスを明示しないと呼べないです。
std::iterator_traits<std::list<int const>::iterator>::reference
が VC7,1 の STL では int& になってしまうのですが、これは正しいのでしょうか?
std::list<int const> l(1, 1);
*l.begin() = 2;
l.back() = 3;
がコンパイルを通ってしまい複雑な心境です。
>>675 int constって値の要件を満たしてないので
コンテナに入れられないような気がする
677 :
675:2005/07/22(金) 21:02:15
>>676 言われてみればそうでしたね。
vector や deque 以外は、コンテナに入る型が
assignable じゃなくても良いのだと勘違いしていました。
678 :
662:2005/07/22(金) 21:44:51
>>663 >それは逆に君が
>VCSTLが以前と比べどのように改善したのか
>述べてくれるといいと思うよ。
いかにも2ch的な反応ですね(苦笑)
それでは実際に自分が体験した範囲でだけ述べます。
Ver6と.NET2003との比較では
1.streamクラスでメモリーリークが起きていた。
2.string::push_backが極端に遅かった。
この2点が改善されています。
STLPortとの比較ではVer6の頃コンテナクラスの速度を
比べてみたことがありますががSTLPortの方がやや早かった(数%〜十数%)
記憶があります。
この点は最近テストしてないのでどうなっているかはわかりません。
パフォーマンスの改善もさることながら、一番大きいのは、
仕様の間違いが修正されてる点でしょ。
例えば、list::sort()の比較関数がちゃんと利用できるようになってる点とか。
VC6では使えてなかったのかよ
ベンチとって比較してみればいいのに
>682
ああ、なるほどそれのせいか。
適当なクラスを取るvectorを作って
vector<Choge> v; のように宣言し
v.push_back(v()); とすると
Chogeのコンストラクタが呼ばれるのは分かるんですが
デストラクタまで呼ばれてしまうのは何故でしょうか?
また、呼ばれないような使い方はありますでしょうか?
どなたかご教授頂けると幸いです
685 :
684:2005/07/29(金) 20:44:07
v();って何だ・・・
v.push_back(Choge());
の間違いです。
>>684 v.push_back(CHoge());の間違いだよな。
v.push_back(CHoge())ではこんな流れになる。
CHogeの一時オブジェクトが作られる。(コンストラクタが呼ばれる)
push_backの中の人がvの末尾に引数のコピーが作る。(コピーコンストラクタが呼ばれる)
式が終わったので一時オブジェクトが破壊される。(デストラクタが呼ばれる)
その後、vのデストラクタで要素の開放が行われ、CHogeのデストラクタが酔うその数だけ呼ばれる。
つまりちゃんとコピーコンストラクタを用意すれば無問題。
コピーコンストラクタのコストがどうしても無視できないほど馬鹿でかければ生ポインタやスマートポインタをvectorの要素にする。
>>686 お早いレス感謝です。
v.push_backの挙動について、一時的にオブジェクトが作られるため
デストラクタが必然的に呼ばれるということですね。
デストラクタ内の処理を、一時オブジェクトに行わせたくない
部分を隔離する事で解決しました。
ありがとうございました。
確保したメモリを開放しないとか?((((((;゚Д゚))))))ガクガクブルブル
なんでresize使わないの?
vector<string> vc;
if (!vc.empty()) vc.clear();
cout << "\nEnter a filename of a collection of strings to sort: ";
cin >> filename;
userin.open(filename);
while(userin)
{
userin >> temp;
vc.push_back(temp);
}
userin.close();
としてCase文でファイルにかかれている文字列をVectorに格納しようとしてるの
ですが、ファイル実行後、1回目はうまく読み込んでくれるものの、2回目にファイ
ルを読み込もうとするとプログラムviolationが表示され、強制的にプログラムを
停止しなくてはいけなくなってしまいます。clearの利用方法が間違っているので
しょうか。アドバイスなどありましたら、よろしくお願いします。
>>691 Case文ってなんだ? filename, userin, temp の型は?
とりあえず、 vector はデフォルトで空だから最初の clear() は要らない。
>>692 レスありがとうございます。型は
char menu, filename[80];
ifstream userin;
string temp = "aaaaa";
となっています。
while (done != 1){
cout << "1: ファイルを読み込む." << endl;
cout << "9: Exit." << endl;
cout << "command? : ";
cin >> menu;
switch (menu) {
case '1'{
if (!vc.empty()) vc.clear();
:
: //691の内容
}
break;
case '9':done = 1;
break;
default: cout << "Invalid Command Try Again." << endl;
のように、2回目以降ファイルを読み込む際に、vcの中身をclearしようとしてい
るのですが、コンパイル後にプログラムを実行すると下記のエラーが表示されて
しまいます。
Unhandled exception at 0x0041f156 in hw5.exe: 0xC0000005: Access violation reading location 0x00000018.
>>693 落ちるのはvc.clear()であってvc.empty()でないのは確実かい?
全然関係ない落ちが待ってそうな悪寒。
>>694 if (!vc.empty()) vc.clear();をコメントアウトし、clearしないで、再度vectorにpush_backしようとしても前の情報が残ったまま、上書きしてくれないようです。結局前に保存した情報が表示されてしまいます(TДT)
>>695 今試しにclear()だけにもしましたが、同様にコンパイル後、実行時にviolationがで
てしまいます。 あと
>>696の追記ですが、if文の一行をコメントアウト時はプログラ
ム実行後もviolationは表示されません。結果をプリントアウトしても1度目に読み
こんだ内容と同じものになってしまいます。なんだろう、、バッファとかそういった問題
でしょうか。
>>696 落ちるのはその表示じゃないの?
1回目はfile読み込み成功して2回目は失敗してない?
>>697 情報小出しウザイ。エラーが再現するソース貼れ。
>>697 どこで落ちるか調べるのにステップ実行できないの?
それがダメなら昔ながらのprintf()挟みまくり。
怪しい箇所をコメントアウトして全体を実行しても見当外れのことがあるよ。
>>691の例ではvcがif (!vc.empty()) vc.clear();のすぐ上で作られてるけど、
>>693では無くなってるよな。
どうせ
>>691のvc生成の記述はデタラメで、本当は別のところに、
まだこのスレで説明していない形で書いてあるんだろ。だから
>>696のようなことが起こる。
情報小出し野郎が示した乏しい情報が、一発目の冒頭からいきなり
実際と違っているケースはよくあるが、今回もそれなんじゃないかと。
userin.close();
のすぐ下に
userin.clear();
を入れたらどうなる?
>>702 @@ -107,7 +106,6 @@
string temp = "aaaaa";
string max="A",min="Z";
int exchange=0, compare=0;;
- ifstream userin;
vector<string> vc;
vector<string>::iterator it;
@@ -129,17 +127,16 @@
{
case '1':
{
- //if (!vc.empty()) vc.clear();
+ vc.clear();
cout << "\nEnter a filename of a collection of strings to sort: ";
cin >> filename;
- userin.open(filename);
+ ifstream userin (filename);
while(userin)
{
userin >> temp;
vc.push_back(temp);
}
- userin.close();
for (int i=0;i<vc.size()-1;++i)
>>703 はい、 userin.clear(); をつけるまでは、ステップ実行した時に while(userin) の
ループに入っていなかったのが、付けたことによってキチンとvectorに保存できるよう
になりました。しかしまだ上に記述しなかった別の場所に問題があるようなので、今
からそれを調べてみようと思います。ありがとうございます。
>>704 ありがとうございます!なんだかウソのように直りました! 違いについては今から勉強し
てみます。本当にありがとうございました。
>>706 いずれの回答も、キーワードは「ストリームの状態フラグ」だ。
>>707 関連した参考ページをたくさん見つけることができました。ご親切にありがとうござい
ます。あとSTLのスレなのに、汚してすみませんでした。
なんだ、std::ios::failbitの下げ忘れか。
>>686 >コピーコンストラクタのコストがどうしても無視できないほど馬鹿でかければ生ポインタやスマートポインタをvectorの要素にする。
一旦、空のデータをpush_backして
data[data.size()-1].setValue();
のほうがコスト少なくない?
SETまたはxtreeを修正し、データの比較回数、移動回数を調べたいのですが、
そういった場合は、xtreeの中にカウンターを設けるべきでしょうか。何かアドバイスな
どありましたら、よろしくお願いします。
>>710 コピーコンストラクタのコストが無視できないほど馬鹿でかい時って、
大抵は「引数をとらないコンストラクタ + データセット」のコンボも負けずにでかくないか?
>>711 xtreeなんて標準にないぞ。まぁ、他スレでVCのSTL弄れっていう宿題を
質問している香具師だろうけど
>>710 一般的には、
push_back() の時点でコピーコンストラクタが呼ばれるんだから意味が無い。
格納する型が「空」という状態を持つとは限らない。
つまり、格納する型が「空」という状態を持ち、且つ
「空」のインスタンスのコピーはコストが無視できるという条件付きで
そのやり方のほうがコストが少ない。
boostとかにコピーコンストラクターのコストかからない配列ないの?
>>715 boost::shared_ptr<std::vector>
boost::shared_array
だからなんでresize使わないの……
resize使うとコンストラクターの初期化処理がされなかったような.
class CData{
public:
int *pointer
int data
CData()pointer(&data) {}
setVal(int v){data=v}
};
std::vector<CData> dataArray;
dataArray.resize(100).
dataArray[3].setVal(3);
std::cout << *dataArray[3].pointer;
どうなると思う?
>>718 デフォルトコンストラクタとデストラクタはちゃんと呼び出されます。
嘘書くな。
だいたい、「コンストラクターの初期化処理」ってなんだよw
CData::CData() : data(0) //←コンストラクタの初期化処理ってこれのことか?
{}
下記のプログラムでエラーを吐かれるのですがどうしたらいいでしょうか。
#include <vector>
#include "position.hh"
int main(){return 0;}
position.hh:15: error: ISO C++ forbids declaration of ‘Vector3’ with no type
position.hh:15: error: invalid use of ‘::’
position.hh:15: error: ‘Vector3’ declared as an ‘inline’ field
position.hh:15: error: expected ‘;’ before ‘<’ token
position.hh:17: error: ‘Vector3’ has not been declared
position.hh:17: error: expected ‘,’ or ‘...’ before ‘<’ token
position.hh:18: error: ‘Vector3’ has not been declared
...
position.hhの15行目 inline Vector3<float>& get_pos();
position.hhでもSTLはまったく使っていないのですが、
自前テンプレートクラスのVector3の部分でエラーが出ます。。
また、STLをインクルードしないでposition.hhを使っている分にはエラーは出ないのですが。
>>723 ・インクルードする順番を変えてみる。
・position.hhの1-15行を晒してみる。
>>724 Vector3がtemplateクラスとして宣言されてないように見えるな
インクルードの順番を変えたら違うエラーが。。
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/bits/stl_bvector.h:426: error: ‘vector’ is not a template
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/bits/stl_bvector.h:821: error: wrong number of template arguments (2, should be 1)
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/bits/stl_bvector.h:426: error: provided for ‘template<class _Alloc> class std::vector’
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/bits/stl_bvector.h: In member function ‘void std::vector<_Alloc>::swap(int&)’:
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/bits/stl_bvector.h:823: error: request for member ‘_M_impl’ in ‘__x’, which is of non-class type ‘int’
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/bits/stl_bvector.h:824: error: request for member ‘_M_impl’ in ‘__x’, which is of non-class type ‘int’
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/bits/stl_bvector.h:826: error: request for member ‘_M_impl’ in ‘__x’, which is of non-class type ‘int’
/usr/lib/gcc/i386-redhat-linux/4.0.1/../../../../include/c++/4.0.1/bits/vector.tcc: At global scope:
...
position.hhの頭は、
#ifndef _POSITION_H
#define _POSITION_H
#include "vector.hh"
namespace namae {
/*!
@brief 3d position class
*/
class Position
{
public:
inline Vector3<float>& get_pos();
inline const float* get_pos_vec(); //irane('A`)
inline void set_pos(Vector3<float>& spos);
inline void move_pos(Vector3<float>& spos);
protected:
Vector3<float> pos;
};
}
こんなかんじです。
Vector3は
template<class Ctype>
class Vector3
{
protected:
//class member value
union {
struct {
Ctype x, y, z;
};
Ctype vec[3];
};
...
と、templateクラスなんです。(今まで普通に使ってきましたし)
vector.hhの中身は?
Vectorもnamespace namaeに入ってる?
違うならusingか::指定が必要だが
postion.hhでusing namespace stdしていて、vector内の宣言とぶつかっているとか?
vector.hhはVecotr2,Vector3,Vector4が宣言してあって、
全部namespaceに入ってます。。
732 :
730:2005/08/05(金) 15:07:31
うわ、既に貼られてたか。
vector.hh内でvector内の宣言と名前がぶつかっているって落ちっぽいね。
namespaceをきちんと正しく宣言し、無闇とusing namespaceしないこと。
vector.hhのusing namespaceを消してnamaeeee::に置き換えましたが、エラーは消えず。
手作業で疲れました。。
>>723 >position.hh:15: error: ISO C++ forbids declaration of ‘Vector3’ with no type
>position.hh:15: error: invalid use of ‘::’
invalid use of ‘::’の::はどれ?
晒してる?
情報を小出しにする人って嫌い。どっかのロダにプログラム毎上げれ。
>>736のbklで main.cppとして
>>723の3行を貼り
g++ (GCC) 3.3.5 (Debian 1:3.3.5-13)
で-Wallでコンパイルしてみたが
何も言わずコンパイル成功。。
マジデスカ。
私の環境が悪いのかしら。gcc バージョン 4.0.1 20050727 (Red Hat 4.0.1-5)
makefileが腐っているか、ディレクトリを別けてtestでやってるのがダメなのかと思い
bkl内に
>>723のmain.ccを作る。これで
>>737とまったく同じ状態だとおもうんですが、結果は
g++ main.cc
position.hh:15: error: ISO C++ forbids declaration of ‘Vector3’ with no type
position.hh:15: error: ‘Vector3’ declared as an ‘inline’ field
position.hh:15: error: expected ‘;’ before ‘<’ token
position.hh:17: error: ‘bkl::Vector3’ has not been declared
...
涙そうそう
>>739 関係ないのかも知れんないけど
このへんはどうかな?
$ cat morio2.diff.gz.base64
H4sICIIj80IAA21vcmlvMi5kaWZmAKVVwY6bMBA9l6+YXiIWcAC3dBPSriL1XvXUS1WtCJBd
VIKRYVF3q/57DQYCxHZIwsXAe/NmPH4aR8l+D+jlG4UDoQnBS0Kf7IKG9u53auekSMqEZMvn
5xYWQRpC6Ez0O+w4HnJWyPHA9XwP+9hbOt0DprN2HM00TUWWkcS9j1c+/nQisd0CcrHlsm++
bLcahGlQFPC9ldLgrwb5yy5NQl9DAEmWJlkMP+KwJPTD531KgvJhAU9x+ciy63ebASkkWVFC
QzE6xmMVh2NWRZIIijae7cL3p+IFQ05DDqSKz8aYoCqVoaoaGTy7uI47qyoAYE2lpGRwHPn1
95gJjLfRIpXZqiZAYLUekBmtJ1xrM7EAM9nax1hosvuV5a7B5Ettsn7D+tfyNWcn+seC9u21
f3vjreqY/Kg4tq9+/qrR2hRd6xrkAUge04D9AKTf8ePdqFhmqzvGF1DJgxeD6C/ScGVWdFNW
dGVW46asxpVZ7Zuy2lfvlTslnLu3jn5mL5eo2kPV4ygSWlQET7w5bNmRrnAjb5I48WXKU8fJ
lY0LlaeukivbFypPnaOqeXqqslLVx3nqDllhRx2oR1x3zcyYhj1VMA6b+9z5aLmYXeh8rYdt
HcZ5wa44Om74F6tmZUboQYEvGkKQJm+xPm7MOHDYi1FEM8V5KRFhVy0lkT5NkSumBYSUFAWP
k8wK1wIJgm/RzUcWFG9hyuqaIxMXVDsqc5bEICX8a0xmG++1/8ZdaxK+CgAA
$ < morio2.diff.gz.base64 base64-decode | gunzip - > morio2.diff
>>740 エラーが1行だけ短くなりました。
>>739の'inline'てやつです。
クラス宣言のときはtemplateの型を書かなくてもいいなんて始めて知りました。というか書くのは間違いなんですかね。
あとusing namespaceを消したときに気になってたんですが、例えば
template<class Ctype>
Vector2<Ctype> Vector2<Ctype>::operator +(const Vector2<Ctype>& v) const
は
template<class Ctype>
bkl::Vector2<Ctype> bkl::Vector2<Ctype>::operator +(const Vector2<Ctype>& v) const
とするだけで、引数にbkl::は付けなくてもダイジョブなんですね。戻り値には付けないとエラーになるのが超不思議です。
無名の構造体が云々言うエラーが出たのでunion/struct含めてカット、
get_vec()でvecを返す代わりに& xを返すように修正。
$ g++ -Wall -pedantic main.cc
$ g++ --version
g++ (GCC) 3.3.1 (cygming special)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ cat main.cc
#include <vector>
#include "position.hh"
int main(){return 0;}
$ pwd
/cygdrive/c/tmp/morio2/src/bkl
なんだろね。いっそRedHatのvectorを疑ってみるか?w
>>742 言われた通り疑ってSTLport(5.0-RC4)を使うようにしたらwarningすら出ないでコンパイルいけました!!!
みなさんお騒がせして済みませんでした。ありがとうございました。
#でも他の環境だと通るのはなんでだろう、、、
744 :
742:2005/08/05(金) 23:39:52
RedHatのvectorに余計なことが書いてあるに違いない。
つーことで、乙。
こんなことくらいでstlを嫌いにならないでね。
745 :
デフォルトの名無しさん:2005/08/11(木) 15:11:32
std::stringでフォーマット出力を使いたいのですが、メンバとしてないでしょうか?
ありません。
std::stringは一般的に文字列の加工用のメソッドしかないと思っていいかと。
#検索や抽出関係は豊富です。
フォーマット出力はstringstreamを使えと言うことなのでしょう。
>>745 1. std::stringstream を使う
標準の範囲内で完結できる
2. boost::format
外部ライブラリに依存するが、簡単で割と多機能。
748 :
デフォルトの名無しさん:2005/08/12(金) 00:14:03
stringをキーとして、データがvectorの連想配列を作ろうとしたのですが、
コンパイルエラーが出てうまくいきません。どうすればいいでしょうか?
map<string, vector<double>> m;
map<string, vector<double> > m;
初歩の初歩だな。
751 :
デフォルトの名無しさん:2005/08/12(金) 00:37:55
>>749さん
うまくいきました。
STL使いへの道は長い(´・ω・`)
まぁこれは仕様のほうにも非はある。
int hoge[] = {0, 1, 2, 3, 4, 5} ;
みたいにvector を初期化、あるいはいっぺんに要素を追加する方法はありますでしょうか。
>>753 Boost Assignment Library
std::vector<int> v;
v += 1, 2, 3, 4, 5, 6, 7, 8, 9;
STLの範囲なら
int hoge[] = {0, 1, 2, 3, 4, 5} ;
std::vector<int> v(hoge, hoge+6); // 初期化
std::vector<int> v;
v.assign(hoge, hoge+6); // 初期化
v.insert(v.end(), hoge, hoge+6); // 追加
ってなやり方しかねえかな?
>>755 std::vector<int> v(hoge, hoge + sizeof(hoge) / sizeof(*hoge));
そう書こうかと思ったけど面倒でねえ
ちなみにsizeofの後ろの括弧は要らんぞ
758 :
756:2005/08/12(金) 12:10:53
>>757 知ってる。けど習慣でね。
sizeof hoge / sizeof*hoge
だと分子がhogeみたく見えるし。
括弧をいかに減らそうか考えるような人はコーディングに不向き。
数学数式のような美しさを求める人とほぼ同レベル。つまり初心者。
俺様宗教の結論部分だけ並べられてもな・・・。
>>760 テキストエディタで括弧の前後に移動できるメリット。
Grepをかけたときの曖昧さを減らすメリット。
各演算子の優先順序に対する曖昧さを減らすメリット。
「使わなくても良い」を「使ってはいけない」に脳内変換する宗教信者もコーディングに不向き。
やっぱ宗教だ。
全然説明になっていない。
宗教の定義。
・教祖がいる。
・教典がある。
俺は配列の要素数を求めたいときにsizeofを使うなら常にマクロか関数にしている。
for_eachと単純なforループは,
fuctorの中でコピーコンストラクター呼ばれないようにしさえすれば
計算速度は同じだよね?
>>763 ・マルクス
・資本論
とかですね。「宗教はアヘン」だそうだが厳密には「異教は(ry」なわけで。
「sizeofの後ろの括弧は要らん」がそんなに気にさわったのなら
あやまるよw
>>768 まあ、怒るほうも怒るほうだとは思うが、わざわざ言うほどのことでもなかったろうね。
演算子の優先順位の話とかでも、ときどきある騒ぎ・・・
771 :
756:2005/08/13(土) 02:44:32
一応言っておくけど、私ゃ気にしてないからね。
#つーか、>755に対して突っ込みを入れる時点で自分も突っ込まれることは想定済み。
なにしろ教祖様の書き下ろしだからな。貴重なんてもんじゃない。
このスレ覗いただけで寿命が3年伸びるよ。
かっこいいいい!
arigataya
776 :
デフォルトの名無しさん:2005/08/14(日) 20:48:44
wstringを、stringとかchar* の文字列に変換したいのですが
どうしたらよいでしょうか。
778 :
デフォルトの名無しさん:2005/08/15(月) 12:40:18
>>777 ありがとうございます。
wstringをstringに変換しよう↓のようにやってみました。
しかしなんだか半角で「ヘヘヘヘヘヘ・…ンンンンンン」みたいな結果になります。
何か原因と考えられる事はあるでしょうか?
string narrow(const wstring& input) {
char* buffer = new char[input.size() * MB_CUR_MAX + 1];
wcstombs(buffer, input.c_str(), input.size() * MB_CUR_MAX);
string result = buffer;
delete[] buffer;
return result;
}
/////////////////////////////////
wstring text;
text = L"こんにちは";
MessageBox(NULL,narrow(text).c_str(),"",MB_OK);
どこがSTLの相談なんだか。
780 :
デフォルトの名無しさん:2005/08/15(月) 13:24:06
どこで聞くべきでしょうか。問題がどこにあるのか分からないので
stl知らない人に聞いて通じる話なのか分からないのです。
あれかなあ、
MessageBox呼ばれた時点でスタック破壊って感じ?
>>780 > stl知らない人
それ、自分に向けてるんだよな?
おまえ、STLってどういうものかわかってるか?
783 :
デフォルトの名無しさん:2005/08/15(月) 13:52:39
>>781 つまり、、、どこが悪くてどう直したらよいのでしょうか。
narrow(text).c_str()
ここが悪くて
wstring text;
text = L"こんにちは";
string result = narrow(text);
MessageBox(NULL,result.c_str(),"",MB_OK);
こう直したらよいんじゃないかなあ
>>780 std::stringはSTLじゃないが標準C++ libraryの所属なので
そのあたりは普通のC++スレの範疇では
>>778 main()の先頭でstd::locale::global(std::locale(""));しないとロケールが
合ってない。
787 :
778:2005/08/15(月) 18:38:12
>>784-786 ありがとうございました。
std::localeの設定で半分くらい解決しましたが
なんだかまだちょっとおかしいのでC++スレ行ってきます。
stringってSTLかと思い込んでました。すいません。
>>785 iteratorが用意されてるのにSTLでないとは初耳だな。
>>788 iostream にもイテレータは用意されているけど、STLに含まれるとは聞いたことがない。
というか「iteratorが用意されているからSTLである」という前提が
いい感じに狂ってて笑えます ;-)
まぁまぁ。規格に載ってない用語についてどうこう言ってもしょうがないでしょう?
そんなこと言い出したら、このスレの存在自体が問題になるのだが
つまりね、「○○パターン」という言葉で相手に意図が伝わってほしいのと同様、
「STL」という言葉は、C++プログラマ同士で同じ意味を持つべきなんですよ。
規格とか関係なく。
まあSTLというものを知らなかった奴が
指摘されて逆ギレしてるだけだから>規格云々
>>798 質問の意味がまったくわからん。
聞いたことがないということの具体例って、たとえばどんなのだ?
>>796 その点、std::string は STL に含むよ派と含まないよ派がいるのよ。
で、重複スレだって言われるのは
>「STL」という言葉は、C++プログラマ同士で同じ意味を持つべきなんですよ。
そもそも STL を標準ライブラリと分ける意味がない、って理由なわけで。
俺は使うときに型を明示しないといけないのがSTLだと思ってた。
vector<int>←コレ。アルゴリズムとかはオマケみたいな。
まぁ、クラステンプレートで且つ標準ライブラリなのに
スタンダードテンプレートライブラリには含めない、ってのも
変な話ではあるんだけどな。
http://pc8.2ch.net/test/read.cgi/tech/1104898734/562 (
>>24)
562 名前:デフォルトの名無しさん[sage] 投稿日:2005/05/05(木) 02:58:39
"STL"なんて呼称の範囲は、C++の標準ライブラリに
取り込まれてしまった今となっては明確に区切れる物では無い。
HP STL や SGI STL のことを指して言ってるのかもしれないが、
今使われてるのはそれらをベースにしたC++標準ライブラリだ。
範囲が明確に決まってるかのように、含まれるだの含まれないだの言うのは時代遅れだぞ。
このスレが不要である事に疑いの余地は無い。
じゃ、もうこないでね。
>>800 > その点、std::string は STL に含むよ派と含まないよ派がいるのよ。
STLをちゃんと知らない奴がでかい顔してる、というただそれだけのこと。
メイヤーズは含めてたっけ。
へー、STLとはコンテナとアルゴリズムの総称だから、MyClassに対して
std:::vector<MyClass>やstd::list<MyClass>という使い方をする人は山ほどいるけど
std::basic_string<MyClass>という使い方をする人がそんなにいるのか。
で、STLの元はSGIだかのコンテナと、(たぶんlisp由来の)アルゴリズムでしょ。
そもそも、これらのコンテナがC++標準ライブラリに含まれることが決まり、
それを「STL」という名で呼ぶことが一般的になったときに
C++には標準的な文字列クラスなどというものは無かった。
STLが標準に含まれたために、
そのインターフェースにあわせたbasic_stringクラスが作られ、標準に取り込まれ、
同時にiostreamもtemplateを使った物に書き直された、
というただそれだけのこと。
本当にMayersがbasic_stringをSTLに含まれると言っているのならば
どこでそう言及しているのか俺にも教えてくれよ。
俺も少しは考えを改めるかもしれないから。
「標準ライブラリ」に含まれるのと「STL」に含まれるのとは違うのだけど
それを読者/訳者がちゃんとわかっていない可能性があるからね。
で、手元にあるMore Effective C++ (初版第3刷)の4ページにおいては
> 使えるときにはいつでも私は標準ライブラリーからデータ構造を用いる。このような
> データ構造は、標準テンプレートライブラリー(Standard Template Library: STL)から
> 引っ張ってこられる。STLには、ビット集合(bitset)、ベクトル(vector)、リスト(list)、
> キュー(queue)、スタック(stack)、マップ(map)、集合(set)、などが含まれるので、
と、basic_stringについては触れてないね。
もちろん、これが書かれたときにbasic_stringが無かったのかもしれないけど。
>>807 Effective STL 第0章。
「STL」に公式の定義はなく、この用語を使う人によって異なるものを意味している。
本書では、「STL」は反復子を利用するC++の標準ライブラリの部分を意味する。
STLには標準コンテナ(stringを含む)、iostreamライブラリの部分、関数オブジェクト、
およびアルゴリズムが含まれる。標準コン(ry
全部読みたきゃ買え。
>>811 「STL=iteratorを用いる部分」という定義に賛同する。
iteratorはC++の言語機能ではなくライブラリ機能なのだから、しっくりくると思う。
みんな私の体目当てにケンカをするのはヤメテ!!
それはイテレーター=イレテーナーということか?
過去にさんざん自分が使ってきた言葉として"STL"に
明確な定義があってほしいという気持ちはわからんでもないが、
現状から考えたらそれは無理だということぐらいわかるだろ?
どこまでいっても穴だらけの定義か、ローカル定義にしかならないんだよ。
馬鹿な2chねらは喧嘩ができる理由があればなんでもいんですよ。
お前のことか
俺のことだよアホ
別スレにしたら?
こんにちは。
std::stringをラッパしたクラスを作ろうとしてますが、(MFCのCStringと同等のインターフェースを持つもの)
クラス名はどのようにすればいいでしょうか。
プロの方の命名をお聞きしたいです。
よろしくお願いします。
プロはそんなことせずにboostを使う。
boostの理解を深めたいのですが、
このサイトだけで問題ないでしょうか?
追加して本を買いたいと思うのですが、
boostを学習する上で助かる参考書はありますか?
ご返答いただけると助かります。
充分じゃんーの?
あと、入門にはLet's boostがいい。リンクから、いくつかboost研究のサイトにもいけるし。
826 :
デフォルトの名無しさん:2005/08/29(月) 17:46:40
mapからequal_rangeで検索して、
見つかった範囲内から更にvalueの一致するイテレータを返す関数を作っています。
このとき、見つからなかった場合にポインタで言うNULLみたいなものを返したいのですが、
なにを返したらいいんでしょう?
endはどうだろう。
828 :
sage:2005/08/29(月) 19:10:45
>>827 ありがとうございます。
試してみます。
boost::optionalという手もある。
そういうときはNILを返すんだよ
>>829 標準アルゴリズムとの整合性をとる意味でも、end() 返しておけばいいところを
わざわざ boost::optional 持ち出すことも無いだろうと混じれ酢
boost::optional が活躍する場合は、
1. 戻り値をポインタではなく値で返したいが、
DBNull のような無効な値も戻り値で返したい場合
2. try-state なテキストボックスやチェックボックスの値と状態を、
戻り値で一気に取得したいとき
くらいだろうか。
それ以外の場面では、NULL 返すなり、end 返したほうが分かりやすい気がする。
VC6の bitset ってバグ有り?
bitset<32> bsVal;
cout << bsVal[0]; // NG
cout << bsVal.test(0); // OK
836 :
デフォルトの名無しさん:2005/09/14(水) 15:54:42
安達祐実ができちゃった結婚か。やるなぁ。。。
ロリ婚
避妊はせなならん
黒田アーサーと別れて4ヶ月で種付け完了、という計算になるわけだが。
どんどん出世していくと苦手な役職についた時に出世がとまる
だから上司は無能ばかり
そういう話があったけどこれって
色々な男とヤリまくってデキちゃったら結婚
だから旦那はDQNばかり
って置き換えられるよね
デキちゃった結婚というのが未だに理解できん。普通、避妊しない?
って、スレ違いじゃねぇかああぁぁぁぁぁぁぁっっっヽ(`Д')ノ
出来てから否認したりして。
生一丁はいりまーす
お前ら、STL のネームスペース std は STanDard ( 標準 )の略であって、
Sexually Transmitted Disease ( 性感染症 )のことじゃないんだぞ。
/\___/ヽ
/'''''' '''''':::::::::\
. |(○), 、(○)、.:|:
| " ,,ノ(、_, )ヽ、,,"".:::|:
. | ´,rェェェ、` .:::::::::|:
\ |,r-r-| .:::::/…
,,.....イ.ヽヾ`ニニ´ーーノ゙-、.
: | '; \_____ ノ.| ヽ i
| \/゙(__)\,| i |
> ヽ. ハ | |
,, --──-- 、._
,.-''"´ \
/ ヽ、
/ (Φ), 、(Φ) ヽ
l `ー ,,ノ(、_, )ヽ、,,. l またまたご冗談を
.| /// `-=ニ=-. /// |
l `ニニ´. l
` 、 /⌒⌒i /⌒ヽ /
`/ | | \ /
冗談は顔だけに(ry
すみません。
STLのvectorでイマイチ使い方が上手くないようなのですがご教授ください。
//要素を1つ増やして、増やした要素のインデックスを取得したい
mBin.resize(mBin.size()+1);
return (mBin.size()-1);
//領域を確保して、確保した領域を0で初期化したい
vector <char> mBin;
mBin.resize(Size);
memset(&(mBin[0]),0,sizeof(char)*mBin.size());
とかやってるんですけど、バグってないでしょうか?
また、もっといいやり方ってないでしょうか?
>849
前者はそれでおkだと思う
後者は
vector<char> mBin(Size, 0);
という1行だけで可能。これの第2引数は char で0を指定する場合、省略可能。
C++ ではそれなりの理由がない限り memset の使用は推奨できない。
>>849 size() の呼び出しがダブってるのが気に入らない。
vector_type::size_type const prev_size = mBin.size();
mBin.resize(prev_size + 1);
return prev_size;
>>849>>850 std::vectorに限りstd::memeset()でいいだろ。
それからstd::vectorのデフォルトコンストラクタは、領域をゼロで初期化するので、
resize()した時点でちゃんとお望み通りの状態になってるよ。
>>852 俺はmemsetはいいと思うが、850の書き方のほうが短いからいいと思う。
>>850-853 即レスありがとうございます。
使わせていただきます。
memsetに関しては不安があったんですよね。
「もしかして、ヤバイとこクリアしてるかも」って思いまして。
ただやっぱりvector <MyClass> mBin;とかの場合はmemsetは駄目ですよね。
ありがとうございました。
>852
>std::vectorに限りstd::memeset()でいいだろ。
POD の std::vector ならね
STLのListについての質問。
ある要素を指しているite1が、ite2の前に新しく要素を挿入した後も、
引き続き同じ要素を指しているようにするには、
if (ite1 == ite2)
ite1 = list.insert(ite2, p); // ite1が宙ぶらりんにならないように
else
list.insert(ite2, p);
とすりゃいいいんだよね?
GCCのlibstdc++なんかだと
std::stringがスレッドセーフではないという非常に痛い状況ですが
みんなどうしてんの?
>>859 string だからって、他のライブラリオブジェクトと比べて
特別な対策が必要とは思わない。
何の話?
ライブラリオブジェクトがC++に関係あるのか?
863 :
デフォルトの名無しさん:2005/09/25(日) 04:11:27
いたたたたたたたたたた
864 :
KKK:2005/09/25(日) 10:28:01
C++のstringって、固定長にできないんですかね??
うん、できない。
866 :
KKK:2005/09/25(日) 10:43:21
>> 865
てことは、
stiring str = "abc";
str.max_size(); ←このサイズは常に確保されてるってことですか?
>>866 いや、必要に応じて拡張されていく。
今どれくらい確保しているかはcapacity()で知れる。
実際に使用している量はsize()あるいはlength()。
>>864 >>KKK⇒きっと、きっと、楓さん
stringを固定長にして何がたのしいの。
組み込み系でSTLって使っていいのかにゃ?
メモリ使用量の予測がたたんから>870
>>871 malloc() 使ってがんばった可変長配列は良くて
std::vector はダメってことか?そんなわけないよな?
あと、 algorithm なんかは問題なく使えるはずだ。
>>872 そうじゃなくて、テンプレートのインスタンス化がテンプレート引数毎にそれぞれ行われるから、
C++ソースの見かけ以上に機械語のコードが膨張してしまいやすいので、
実行する機械語のコードのサイズの予測が立たないということ。
そこでstd::vector<void*>ですよ
それは設計が悪いか、アセンブルリストを読めないか、その両方なのでは?
やっぱ、アセンブリソース見んとだめでつか。
やっぱ組込はC++よりJavaだな
いいよ別にアセンブリで書くから。
きついのは最初だけだし。
879 :
デフォルトの名無しさん:2005/10/01(土) 11:21:21
STL使うとソースコードのサイズが膨らむからと言って
独自のIntArrayとかStringArrayとか作ってたりする?
>>879 そういうことをしないとSTLが生き残れない過酷な環境もあるのです
>>873 コードサイズなんか予測に頼らなくてもマップファイルで確認できるだろ。
そのマップファイルで確認できるコードサイズが
どれくらいになるかの目処が建てづらい罠
>>882 やってみればすぐわかることなのに、
なんで頭の中で目処を建てないといけないの?
マップファイルも結果のうち。
マップファイル上でいくらになるかを予想する。
(それが予想しづらいのがテンプレートを使ったとき)
こう書けば気が済むか。
>>883 はぁ。そうですね(呆
保守頑張ってください。
>>884 なにそれ?数当てゲーム?
予想してからマップファイル見て「わーいピッタリだぁ」とかすんの?
ごめん、やっぱり意味がわかんない。
予測が立てづらいのではなく、コードのサイズがでかくなりやすい。
だから少しでもメモリをケチりたい組み込みではテンプレートが嫌われやすい。
>>883 すでにソースコードがあることが前提の発言だなw
>>889 使うか使わないかの話してるのに、
ソースコードが無いってどういう状況だ?
使うか使わないかって何を?
最初にプロジェクトで使っていくか使わないか検討しないの?
>>893 問題なく使える箇所では使えばいい。
問題が発生する箇所では使わなければいい。
全体で2択を迫る意味がわからない。
>>894 >問題なく使える箇所では使えばいい。
>問題が発生する箇所では使わなければいい。
はぁ、それからどういう展開があんの?
もしかしてこれでおしまい?
>>895 シラネーヨ。どんな展開期待してんだ?
はじまりが >869 だからこれで終わりでもいいだろ。
STL使わない&プログラムサイズ削減というと、昔ながらのvoid*コンテナを
使うのか?
899 :
デフォルトの名無しさん:2005/10/01(土) 19:16:31
思考停止しますた
>>894 それで済ませるためには、マップファイルとかを読むなどして
問題の原因となっている箇所を特定できる能力が必要だろ。
それができない人(が居ないプロジェクト)は、使っちゃいけないんだよ。
そして「使っちゃいけない」理由が
自分にその能力がないことだと認めたくなくて、
もっともらしい理由を求める人がいる、のかもしれない。
903 :
デフォルトの名無しさん:2005/10/01(土) 19:42:24
>>903 改定されそうだからという理由は覚えなくて良いという理由にはなるかもしれないが、
それが普及するまで時間もかかるだろうし、今のSTLを触れておくくらいやっても損はないよ。
>>903 右辺値参照というか move semantics のサポートは現在の標準ライブラリに
+α として導入されるもので,現在のもの対する理解が不要になるということは
全然ないんじゃないんですかね.auto_ptr こそ deprecate されますけれど,
auto_ptr が持つ破壊的コピーのセマンティクスの考えも,move semantics に
直接つながるわけですし.
>>903は、ちゃんと内容を理解して、発言してるんか?
908 :
デフォルトの名無しさん:2005/10/02(日) 06:26:45
unique_ptrは実際にそれ自身の提案に相当します(そして得るだろう)。
しかしながら、それは、完全のためにここで含まれています。それは、
rvalue参照および動き意味論に関しての非常に重要なライブラリー・
コンポーネントです。unique_ptrは完全に、
後ろに互換性をもたないauto_ptr置換です。したがって、auto_ptrを
大いに非難し、かつauto_ptrを単に固定する代わりに、新しい名前
(unique_ptr)を導入する必要。主な類似性、およびunique_ptrとauto_ptrの
間の差は次のものを含んでいます:auto_ptrのようなコピー・シンタックスの
代わりにlvaluesから動きシンタックスで移動します。しかしながら、それは
ちょうどauto_ptrのようなコピー・シンタックスでrvaluesから移動します。
auto_ptrと異なり、lvaluesから移動する(あるいはコピー)ことを拒絶します。
これは総括的なコード中の安全性の鍵です。それがちょうどauto_ptrのように
、ローカルの自動変数である限り、コピー・シンタックスと共に、機能から
1つ返すことができます。デフォルトdeleter(また「空の」deleters)で、
それはauto_ptrと同じオーバーヘッド(1つのポインター)を持つことができま
す。deleterは参照タイプでありえます。deleterは「ヘビー級」でありえま
す、コピーしない、可能な(そして)移動されました。非デフォルトdeleters
で、他のRAII機能性は達成することができます。配列形式を扱う特殊化があ
ります。配列形式は単に特別のdeleterを越えるものです。インターフェース
は、配列に、より適切な一つに変更されます:
909 :
デフォルトの名無しさん:2005/10/02(日) 06:44:14
unique_ptrは完全に、 後ろに互換性をもたないauto_ptr置換です。
移植性なんか元々ないのよ。全部書き換えてください。
いい加減、C++D言語とでも逝ってほしいです。
命名するならC&&D言語がいい。
910 :
デフォルトの名無しさん:2005/10/02(日) 06:50:25
くだらない
第53回ポインタの安全な使い方(第x回?)
この連載では、今まで何度となくポインタとうまくつきあう方法について
考えてきました。それくらいポインタには悩まされるわけなのですが、
今回は、じゃあポインタがどんな場面で実際に使われるか、という視点で
ちょっと見ていきたいと思います。
これでいいじゃない。
include <memory>
#include <vector>
struct Base {virtual ~Base() {}};
struct Derived : Base {};
int main()
{
typedef std::unique_ptr<Base> BasePtr;
typedef std::unique_ptr<Derived> DerivedPtr;
std::vector<BasePtr> v(3); // 3 default constructed BasePtr's
v.resize(2); // No copy constructor required
v.push_back(DerivedPtr(new Derived)); // No copy constructor required
v.front() = DerivedPtr(new Derived); // No copy constructor required
v.insert(v.begin(), DerivedPtr(new Derived));// No copy constructor required
v.erase(v.begin() + v.size()/2); // No copy constructor required
// BasePtr p = v[0]; // will not compile, copy constructor required
BasePtr p = std::move(v[0]); // ok, ownership transferred to p
}
自動翻訳ってもっとひどいもんだと思ってたよ。
鼻つまんで読めば大筋くらいは把握できるな。
ところで、move_ptr が持っている
safe bool をとるコンストラクタと代入演算子って
どんな意味があるの?
913 :
デフォルトの名無しさん:2005/10/02(日) 19:39:42
>自動翻訳ってもっとひどいもんだと思ってたよ。
>鼻つまんで読めば大筋くらいは把握できるな。
そうなんですよ!プログラミングはinfoseekが使えます。
おすすめはしませんが、ヤフーとか面白いですよ。○×★???
>>903 のリンク先の「 deque && 」が気になった。アレは何?
>>916 てゃんks
まだ読んでる途中だけど、
A.Alex が行ってた mojo みたいなのを、言語でサポートしようってこと?
>>917 >A.Alex が行ってた mojo みたいなのを、言語でサポートしようってこと?
はい.ほとんどその通りです.
そう言われてもわかんないだがなぁ・・・
>>919 リンク先の「More on A&&」の項のコード見れば一発でわかるよ
エイリアスのない右辺値がその他の右辺値・参照と区別できれば
所有権を完全に貰える場合と複製でなければならない場合を区別できるわけね。
その結果、コピーを作る手間をかける必要ない場面では移動して効率化できると。
計算式の途中では往々にしてそういう場面があるが
組み込み型だとそういう最適化ができるのにユーザー定義オブジェクトだと
それができなくて性能の制約になってたって感じか。
いまだにそんなプリミティブなところの効率こだわる辺り
さすがC++というしかないな……
>922
あー、はいはい。 速度を気にしないボクちゃんはHSPでも使っててくだちゃいねー。
突然のヒステリー
まさかのミステリー
恥ずかしいヒストリー
>>921の
>性能の制約
って堅牢性も含めて言ってるんじゃないですか? 代入演算子やなんかで、多くのケースで
例外を送出しない保障ができるでしょう。
928 :
デフォルトの名無しさん:2005/10/06(木) 00:11:38
質問です。
vector <MyClass> mMy;
↑と宣言したものにresizeやpush_backなどを行うと
内部的にはどうなるのでしょうか?
MyClassのインスタンスは1回全部破棄されて、
すべて新しく作り直されるのでしょうか?
それとも内部的に持っているポインタの配列(のようなもの?)が確保しなおされて
MyClassのインスタンス自体はそのままなのでしょうか?
>>928 普段は余計にメモリを確保しておいてあるから、そこへresizeやpush_backはコンストラクタを呼ぶだけ。
足りなければ新たにメモリを確保して既存の要素はコピーコンストラクタでコピーされる。
930 :
デフォルトの名無しさん:2005/10/06(木) 00:27:17
>>929 レスありがとうございます。
じゃあ、その余分なメモリで足りなくなった場合は、
既存の要素を一度すべて複製、削除しているということですね?
ということは、そういう確保のしなおしが気になるときは
vector <MyClass*> mMy;
を使った方がよいということでしょうか?
>>930 vector なら reserve() とか。
list<MyClass> でもいいんじゃないかな。
うんにゃ
vector<MyClass> mMy;
mMy.reserve(1000);
とでもしておけば、あらかじめ1000個分確保してくれる1000個までなら
リサイズやらメモリの再配置はない。が、インスタンスを代入するたびにコピコンが動く。
ので vector<MyClass*> mMy;とした方がいいのかもしんない。
933 :
デフォルトの名無しさん:2005/10/06(木) 00:56:18
>>931-932 レスありがとうございます。
とりあえずvector<MyClass*> mMy;で逝っときたいと思います。
934 :
デフォルトの名無しさん:2005/10/06(木) 02:10:53
たびたび申しわけありません。
質問です。
stringであらかじめ領域を確保しておきたいのですが、
reserve関数で確保した領域というのはどういうときに変化してしまうのでしょうか?
例えば
string str;
str.reserve(20000);
str = "";
str += "ABCDEFGHIJK";
str = "";
str += "ABC";
とやってもreserve関数で確保した領域はそのままなのでしょうか?
>>934 そのままです。reserve()で予約した領域を変化させるのは、文字列がreserve()で
予約した文字数を超えるか、再びreserve()を呼び出し、現在の容量または文字数
を下回る領域を指定した時だけです。
二番目の場合は、非強制的な要求なので、保証はされていません。
>>935 レスありがとうございます。
string www;
www.reserve(20000);
int iiiis = www.capacity();
www = "";
int iiii = www.capacity();
www.reserve(20000);
www = "ABC";
int ii = www.capacity();
↑のようなプログラムを書いてデバッガみたところ
www = "";やwww = "ABC";のところでreserveで確保した領域が変更されてしまうようです。
>>936 だとすれば貴方のstd::stringクラスが、代入時にreserve()を呼び出して
いるんでしょう。つねにshrink-to-fitするように。それじゃあreserve()の
意味があまりありませんね。
>>937 レスありがとうございます。
この辺は環境依存ということでしょうか。
開発環境はVC.netです。orz
とりあえずstring使わないでなんとかしたいと思います。
おつきあいいただき、ありがとうございました。
std::string::assign()
STL-port4.6.2とVC.net 2003という環境でboost1.32.0導入してみました。
regexとfilesysutemが使いたかったのでbjamでvc-7_1-stlportを指定して
インストール。きちんとlibファイルができました。
そこまでは良かったのですが、実際boost::regex,filesystemを使用してみると
リンクの際に未解決の外部シンボルのリンクエラーがいくつか発生しました。
それらがすべてSTL関係っぽいのですが、STL-portとboost間の相性やら
なにかあるのでしょうか?
何か情報がありましたらご教授願います。
以下、発生したエラーのひとつです。
error LNK2019: 未解決の外部シンボル "protected: static bool __cdecl
boost::reg_expression<char,class boost::regex_traits<char>,
class _STL::allocator<char> >::can_start(char,unsigned char const *,unsigned char,
struct boost::re_detail::_narrow_type const &)"
(?can_start@?$reg_expression@DV?$regex_traits@D@boost@@V?$allocator@D@_STL@@@boost@@KA_NDPBEEABU_narrow_type@re_detail@2@@Z) が関数
"public: static bool __cdecl boost::re_detail::access_t<char,class boost::regex_traits<char>,
class _STL::allocator<char> >::can_start(char,unsigned char const *,unsigned char)"
(?can_start@?$access_t@DV?$regex_traits@D@boost@@V?$allocator@D@_STL@@@re_detail@boost@@SA_NDPBEE@Z)
で参照されました。
>>940 作られたLibファイルをプロジェクトに参加させていないだけでは?
class Foo{
private:
vector<A> va;
bool predicate(A a1, A a2) { ~~~ }
public:
void bar()
{
A a(~~~);
find_if(va.begin(), va.end(), bind2nd(ptr_fun(predicate), a));
}
};
↑こんなことやってるんですがpredicate周辺でコンパイルエラーがでます。
「no matching function for call to `ptr_fun(<unknown type>)'」
predicate()がグローバルな関数ならエラー無しで動作するのですが。。
何がいけないのか、どうすれば正しく動くのか、どなたかよろしくお願いします。
>>942 メンバ関数predicate()をalgorithmに適用するには、第一引数にthisを
バインドしておかないと駄目。
面倒ならboost::bindを使おう。こっちの方がはるかに楽。
>>942 メンバ関数へのポインタを得るためには & が必須
且つ同クラス内でも Foo:: の明示が必要。つまり &Foo::predicate 。
あとは >943-944
皆さんありがとうございます。必死こいて調べて、なんとかboostを使ってできました。
ただ、通常のbindを使ったものがどうしても動きません。
bind2nd(ptr_fun(predicate), a)
を
boost::bind(&Foo::predicate, this, _1, a)
にしたものは動いたのですが、
bind2nd(bind1st(mem_fun(&Foo::predicate), this), a)
が動かないのです。thisのバインドの仕方が間違っているのでしょうか。
・・でもどう考えてもboost使った方が簡単そうですね。。
>>946 間違いじゃなくて標準のバインダが貧弱すぎるだけ。
気にせず boost::bind や boost::lambda::bind 使うのが正解。
>>947 mem_fun消してみたんですがまたもやエラーメッセージの洪水をワッとあびせかけられたので
さすがにギブアップします・・・
>>948 はい、これからboost使うことにします。
ありがとうございました。
>>949 結論からいって無理だもん。mum_fun は高々一変数のメンバーしか扱えない。
よって代替のインナー関数オブジェクでも作ってbind2に渡すしかないね。
本当やねえ。SGI STL固有の拡張std::compose2()も、引数の合成ではなくて
関数の合成やから、この場合には適用できへんし。
std::bind1st2()とかstd::bind2nd2()があれば、できたかもしれへんねえ。ま、
boostがあるんやから、そちらでまとめまひょ。
952 :
940:2005/10/11(火) 12:27:21
>>941 レスありがとうございます。
VCの場合、stol-port,boost関連のヘッダがインクルードされれば自動的に
libは読み込まれるはずです。念のため手動でプロジェクトに追加してみましたが
結果はかわりませんでした…。
>>952 >ヘッダがインクルードされれば自動的に libは読み込まれるはず
VCはいつの間に俺の知らない魔法を使うようになったんだ?
>>953 boostが気を利かせてpragmaでlibをリンクするようにしてくれてる。
libpath はどうなんだ?
956 :
940:2005/10/11(火) 17:33:31
957 :
デフォルトの名無しさん:2005/10/18(火) 15:58:28
age
958 :
デフォルトの名無しさん:2005/10/29(土) 00:59:43
boost:serialization を使ってみたところ
error C2027: 認識できない型 'boost::STATIC_ASSERTION_FAILURE<x>' が使われています。
with
[
x=false
]
となるのですが何が問題でしょうか?
>>958 それはboostが意図的に起こしたコンパイルエラー。
エラーが発生した場所に意図が書いてあるはず。
960 :
デフォルトの名無しさん:2005/10/29(土) 01:39:19
// if your program traps here, it indicates taht your doing one of the following:
// a) serializing an object of a type marked "track_never" through a pointer.
// b) saving an non-const object of a type not markd "track_never)
// Either of these conditions may be an indicator of an error usage of the
// serialization library and should be double checked. See documentation on
// object tracking.
BOOST_STATIC_ASSERT(check_tracking<T>::value);
save(ar, const_cast<const T &>(t));
とありました。
track_neverをマークする???
http://hw001.gate01.com/eggplant/tcf/cpp/boost_serialization.html こちらの最初の例題をまねるだけでは動かないものなのでしょうか?
>>960 非 const なオブジェクトをシリアライズしようとしていませんか?
963 :
デフォルトの名無しさん:2005/10/29(土) 02:23:42
>>959、961
ありがとうございます。
右も左もわからない状態でして
MFCを軽く触ったことしかなくて右往左往しています。
>>961 はい 非 constです。
どうやらBOOST_CLASS_TRACKING(Student, boost::serialization::track_never);
とするとOKのようです。
しかし
boost::serialization::track_always
boost::serialization::track_selectivly
ですと上記のエラーとなります。
boost::serialization::track_always
boost::serialization::track_selectivly
にしたい場合はどうすればよいのでしょうか?
964 :
デフォルトの名無しさん:2005/10/29(土) 02:31:49
追記
class Student {
public:
Student(){}
Student(std::string name , int age)
{
name_ = name;
age_ =age;
}
private:
std::string name_;
int age_;
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & name_;
ar & age_;
}
};
上記のクラスで試しています。
>>964 template<class T>
T const &as_const(T &t)
{ return t; }
int main()
{
std::ofstream ofs("hoge");
boost::archive::binary_oarchive ar(ofs);
Student s;
ar << as_const(s);
}
こんな感じで通りませんか?手元の VC7.1 だとこれで O.K. なんですけれど.