STL(あるいはboost)を使っていく上で 思わぬ落とし穴、やってはいけない禁じ手などを 晒すためのスレです。暗黙知の解放!
vector<auto_ptr>
vectorやstringで、.clear()したからといって メモリも解放されるとは限らない罠。
>>2 ん!?危険なの?ちと想像してみよかな・・・
>>4 std::sort()などのコピーを伴うアルゴリズムを呼び出した時の事を考えてみろ。
普通ポインタのコピーをしても、ポインタが指しているインスタンスは変化しないという
考えの元に各種アルゴリズムが構築されている。
しかし、std::auto_ptrは、ポインタをコピーするだけで、元のポインタの値は 0 に設定
されてしまう。これにより、複数のポインタから同一のインスタンスを指す事のないように
してあるのがstd::auto_ptrだ。だからこそstd::auto_ptrのスコープを外れた時点で、それ
が指すインスタンスもdeleteできる。
すなわち、コピーコンストラクタと代入演算子のセマンティックスが独自の物で、通常の
ポインタとは全く互換性がない。
gcc3以降では、auto_ptrをstlコンテナに入れてるソースは コンパイルエラーになるようになってるしね。
auto_ptrはほとんど使わないな。 非常に使いにくい。
落とし穴つったらアレだろ コンパイラが対応してないwwwwww
>>10 STLもまともに機能しない糞コンパイラなぞ捨ててしまえ。
糞スレ立てんなよ、バーカ 死ね>>1
EffectiveSTLに書いてある以外の落とし穴があるなら 是非知りたいけど
>>6 それは、普通でしょう。 auto_ptrはstlのコンテナとは共存できない。
Exceptional C++: Item 37. AUTO_PTR を読みましょう。
ちなみに、auto_ptrをコンテナで使おうとするとエラーが出るのは、Exceptional C++によれば、
auto_ptr's copy constructor and copy assignment operator take references to non-const to
the right-hand-side object. Most implementations of the standard containers' single-element
insert() functions take a reference to const, and hence won't work with auto_ptrs.
とのこと。 boostのshared_ptrは便利だよ。
stringの参照渡しではなく、実体渡しってコスト高いのかな・・・ 例えば、1000文字程度の文字列が格納されてるstringを関数の引数などで 実体渡しだとか、返却すると高いのかな? string tail( string a) { return a + ":addtail"; } みたいなコード。 参照渡しって微妙に使いにくいんだよね・・・だから実体渡しにしたいの だけど。
>>15 stringの実装方法による。大抵のstringは文字列そのものを別の領域にもっており、
コピーコンストラクタでコピーされるのは管理領域だけという場合が多い。
それよりも、関数内での演算時にコンストラクタが呼び出され、そちらはまともに内容の
方もコピーするので、間違いなく遅くなるぞ。
>>15 それでいいと思う。 最近のコンパイラって結構賢いし、あんまり細かいことは気にしない
方がいい。 stringも大抵はリファレンスカウント方式だから、コピーのコストは低い。
ちなみに、C++ではmake copying cheaperは一つの鉄則。 特に、STLユーザーは。
(Effective STL: Item 3参照) C++でもJavaみたいにプログラミングするのがいいみたい。
また、Efficent C++ Chapter 4. The Return Value Optimization参照するといい。
>>16 ,17
ほうほう、なるほど。
んじゃ、stringの場合、もう参照渡しにする理由なんてない
気がするなー。
サンクス。
>>18 Efficient C++でも読んでみるといいかも。
便乗して自分も質問・・・ vector< string > なんかを返却するのは危険だろうか? 例えばの用途としては、ファイル名を列挙するサービスを作ったとして、 その場合、なんらかの形で配列を返しますけど、安全性考えるなら vectorだとか使いたいところ。それも、返却で。 アセンブリリスト出力させても、いまいち分からないし。 特にSTL内部の謎シンボルにcallだとかjumpされるともう追えない (;-;)
>>20 危険でも何でもない。std::vectorのコピーコンストラクタが全部面倒みてくれる。
もちろん参照を返す場合は、ローカル変数の参照を返してはいけない事などは
他のクラスやPODと同じ。
逆落とし穴?ってとこかな。有名だけど、一応足跡残しとこうかな。 vector<>ってアドレス的に連続性が保障されてるって、みなさん 知ってました? 例えば、vector< char > tbl; とあって、tbl.size()==nな場合、 tbl[0]からtbl[n-1]は連続したアドレスであることが保障されてるんだってさ。STLの仕様として。 なので、char*p = &tbl[0] とかやって、その後は *p++ = 0x00 だとかで アクセスできてしまうと。iteratorを使う必要もないみたい。 でもdequeでは、保障されてるのか、保障されてないのか不明。 明記された文書も見たこと無い。 listあたりだと確実に連続してないので、気にならないけど dequeは気になるなー。
>>危険でも何でもない。std::vectorのコピーコンストラクタが全部面倒みてくれる。 あ、いや、おそらく20はそのコピーコンストラクタのコストを気にしてると 思うんですが。例えば、stringが100個くらいあったとして、それを返却すると 関数出口で発動するコピーコンストラクタがまじでコピーしているのか否か?など。
>>22 ISO/IEC14882:2003ではstd::vectorの連続性が保証されてるよ。
§23.2.4の当たり。
std::dequeは保証されてない。
ついでに調子こいて。 vector<bool>の時だけは特殊カスタマイズ発動して、ビット操作を意識した コードが生成されるみたい。ビットセットなんかでメモリかつかつの時は 積極的にvector<bool>を使うといいみたい。
>>23 それだったら、std::vectorの実装による、としかいいようがない。
Copy On Writeなら、要素を変更しようとしない限り、管理情報のみを返すかもしれない。
const参照なら戻り値最適化をしてくれる可能性がさらに高まる。
vector<bool>は
>>25 の理由で正常にサイズが取得できないから使うな、と
聴いたことがあるんだけど…
ビットセットはそのままstd::bitsetじゃダメなん?
>>25 Effective STL第18項。
std::vector<bool>はコンテナの要件を満たしていない。
それよりもboost::dynamic_bitsetの方がまだましだろ。
stringだとか<<だとか使い始めて気になるといえば、 c言語時代のprintf可変調引数って便利だったなと。 %05dで0つめてくれたり。%08xで16進表記してくれたり。 .printf()というか.vsprintf()に相当するユーティってありそうだけど 見たことない。ご存知のかたいますー?
boost::format
>const参照なら戻り値最適化をしてくれる可能性がさらに高まる。 あー、そうかそうか。大抵の用途は確かに結果受け取りの const参照で済むから、これからはこまめにconstつけてこうかな。
>>29 そんなに標準の書式マニピュレータを使うのが面倒か。
std::setw()以外は効果がストリームに残ったままになってしまうので元に戻すのが
面倒と言えば面倒だが。
直接フラグをsetf()/unsetf()でいじってもいいしな。
結構、みなさんboost使ってるんですね。 自分は使ったこと一度も無い。ものにもよると思うんだけど、 「これないと損するから黙って使え!」というくらい強烈なお奨め boostモジュールってある?
boost::bind、boost::shared_ptr
boost::lambda (かなりコンパイラを選ぶ)
boost::regex 手軽に正規表現使うにはいい
boost::mplは基地外のためのライブラリかも。これで書かれたプログラムを見て 発狂しそうになった。
とりあえずスマートポインタを初めとして、 次期標準に入ることが決まってる物は使って損はないと思われ
template <int leftShifts_, int rightShifts_> Int_ convert_(Int_ v) const { return boost::mpl::if_c < (rightShifts_ == leftShifts_), NoShiftPolicy, boost::mpl::if_c < (leftShifts_ > rightShifts_), LeftShiftPolicy<leftShifts_-rightShifts_>, RightShiftPolicy<rightShifts_-leftShifts_> >::type >::type::shift(v); } これ、c++のソースなんですか? 意味不明〜
>>次期標準に入ることが決まってる物は使って損はないと思われ STLくらい標準であれば安心して使えるのだけどねー。 vc++、gccどちらでも同じソースをコンパイルできなければならない仕事を 抱えてるため。 でも次期標準決定してるなら、そろそろ馴れとかねば。
>>20 関数で危険なのは、ポインタやレファレンスを返すとき。 特に、関数内部で作られたオブジェクトを
ポインタやレファレンスで返すのは重大な誤り。
この場合のオーバーヘッドが気になるなら、shared_ptrを用いるとよい。 shared_ptrを用いれば
Javaのようにオブジェクトを扱えるのでメモリ管理を気にしなくてよい。 ただし、構文が少し
煩雑になるという欠点を持つ。 *や->演算子を多用するから。
例:
typedef vector<string> VectorString;
typedef shared_ptr<VectorString> RefVectorString;
RefVectorString v(new VectorString());
v->push_back("Hello");
VectorString::iterator it = v->begin();
cout << *it;
RefVectorString f(){
RefVectorString v(new VectorString());
v->push_back("Hello");
return v;
}
RefVectorString v2 = f();
もOK!
鬱だ… STL
>>42 お前みたいな初心者が出てくると、かえって混乱するから引っ込んでてくれ。
>20 >42 基本的にはどこかで作ったvector<string>を「丸ごとコピーして」 値返しするんじゃない? なので、スタックに積まれたvector<string>でも、戻り値は 「丸ごとコピーした」値なので、ローカルスコープを抜けて 元のvector<string>が削除されても戻り値に影響しないはず。 >26 そんな無茶なRVOあるの? >33 boost::test CPPUnitよりセットアップが簡単。ガリガリ手書きする必要あるけどね。
المغاربيعلىخالتاريخية خصصةلمنالرأي كانتص العاهلالمغربيلموريتانيا،ولكنل
>>15 boost-sandboxにあるBoost.Moveとかも見てみたら良いかも知れませんよ.
実体返しと構文一緒で効率は参照渡し並で(゚д゚)ウマーみたいな.
"Move"の概念がイマイチ浸透してないのとドキュメントが未整備なために
非常に取っ付きにくいライブラリですけれど.
>45
>boost::test
bjamのunit-testルールと組み合わせるとbjamと打つだけで
ビルド後即単体テストな感じでさらに(゚д゚)ウマー.
>>46 だったら、一辺OCAMLやHaskellかじってみたらジェネリックプログラミング
ってなにかよく理解できるとおもうよ
例えばboostのスマートポインタ(shared_ptr)を使うことにした場合、プロジェクト全体で使うように 統一する? それとも複数箇所から参照されるようなオブジェクトだけにしておく?
統一しておかないと、そのうち同一プロジェクト内に複数の リファレンスカウンティングスマートポインタが蔓延する罠。
その場合、生ポインタも禁止?
52 :
デフォルトの名無しさん :05/03/12 08:13:25
std::getline(std::basic_stringを引数に取るもの)も上限指定できないから、 無茶苦茶行数の長いテキストを読み込ませるなんて攻撃ができる。 なんて話をこの前C++スレで見かけたな。
見かけるもなにも有名な話なんで
今時basic_stringがCOWなSTLってあるんですか?
56 :
デフォルトの名無しさん :2005/06/04(土) 16:50:44
>>22 内部の実装はべた配列だ。だからといってメモリのアドレスを取得して(
そもそも iterator がポインタだったする)vector にアクセスするのは間違いだ。
社会に出たらやっていいことと悪いことを見分けなければならない。
内部のメモリポインタを取得して操作したいのなら valarray を使おう。
単純なループをまわすとき iterator を使おうが [] でアクセスしようが、
ポインタを使ったときと同じ速度のコードをはいてくれる。
今時ポインタのほうが速いというのはうそだと思っていいだろう
(もちろんレジスタの割り当てを気にするくらいの限界のチューニングをするときは違うかもしれないが)。
http://www.nantekotta.com/stl.html
57 :
デフォルトの名無しさん :2005/06/04(土) 16:55:33
std::stringの最後は\0とは限らないので、 終端の判別は必ずイテレータが終わりかどうかを調べること。
>>56 vector のメモリレイアウトはC言語の組み込み配列と同じだよ。
そんなメンテナンスされてない古い記事引用して何が言いたいの?
>>58 社会に出たらやっていいことと悪いことを見分けなければならない。
>59 うん、それは当然だと思うよ。で、その言葉にもう一言加えさせてくださいな。 「社会に出たらなぜそれをやって良いか/悪いかを人に納得できるように説明できなければならない」
>>57 イテレータ使ってループ回しておきながら 0 で終端判定ってのは中途半端な間違いだな。
そんな間違いする奴は string の要素に 0 が入ってたりしても嵌るんだろうな。
63 :
60 :2005/06/04(土) 17:18:18
付けたしだけど、私もiteratorでアクセスできる場面でポインタを使うことにはもちろん反対ですよ。 CのAPIとデータをやりとりする際の一時バッファとして利用する場合などでは ポインタによるアクセスは(vectorが空でなければ)安全で有用だという主張です。
ところで >内部のメモリポインタを取得して操作したいのなら valarray を使おう。 これってOKだっけ?valarray自体カビの生えた前時代の遺物なので どうでもいいっちゃどうでもいいんだけど
Cに渡すときはポインタと個数を渡すから ベクタが空でも、個数も0なんで 結局安全なケースがほとんどだと思うが
>>65 C/C++使うんなら未定義動作に気をつける覚悟を持たなくちゃ。
普通定義してあるって・・・
>>67 未定義動作が何のことか知ってて言ってるのか?
>>68 うん。で、何が言いたいの?
まぁどうせ急に絡みたくなっただけなんだろうけど。
>>66 はCの配列とvectorを比較しているわけではなく、
配列の先頭ポインタと個数を渡すというインターフェース自体が
危険だと言いたいのだろう。
72 :
66 :2005/06/04(土) 19:51:58
73 :
70 :2005/06/04(土) 20:11:04
vectorが空の場合にしても、 Cの配列との比較にもvalarrayとの比較にもなってないから、 一体何を言いたいのだろうと考えた結果の結論でした。 失礼。 まだ>56の話かと思ってました。
void hoge(int n, int* ptr) { int i; for(i = 0; i < n; ++i) { hogehoge(ptr[n]); } } みたいな、Cルーチンに、 hoge( &vect[0], vect.size() ); とかやると、本当にvectが空のときだけは動作が未定義なの? そういう無駄なチェックを要求するう糞ったれな仕様は、やめてほしいんだが
hogeがそういう実装なら、nが0の場合はptrはアクセスされないんだから 未定義な訳がない気がするが 一般には、そういう「Cルーチン」の実装によるとしかいえないだろう
ちなみに、引数逆でしたな、すまん
俺が言いたいのは、Cルーチンのほうじゃなくて vectorが空のときに、&vect[0]の動作が未定義かどうかってこと ごみの値でいいから、とにかくポインタを返してさえくれる仕様ならば 何も文句は無い
どうやら、そうらしいな まったくプログラム経験のろくに無い奴が作ったとしか思えん糞ったれな仕様だ 空の時には「未定義のポインタ値」を返すbegin_ptr()とかでもあればともかく 大体STLってのは、馬鹿丸出しの仕様が多い vector<int> v; vector<int>::const_itetator it; 中略 copy(it, v.end(), dest); こんなあたり前のコードが通らねえから、const_castがいるときた const_iteratorを返す、cbegin(), cend()ぐらい用意しとけっての
>>80 名前は c_str() に倣って c_ptr() とかして
空のときはヌルでも返すことにするとよかったかもしれんな。
あと const_cast は要らんだろう、といちおう突っ込んでおく。
vector<int>::const_iterator v_end = v.end(); copy(it, v_end, dest); とかやれば、要らんけど やらんと、it は const_iterator で、v.end()はinteratorだから templateでどっちの型を採用したらいいかわからんといって怒られる
つーかこの場合はconst_iteratorの存在理由こそ問題
84 :
デフォルトの名無しさん :2005/06/05(日) 05:57:19
const_iteratorは俺も嫌い const_iterator ci = v.begin(); iterator i = const_cast< const_iterator >( ci ); これが出来る出来ないよりも、やって良い行為なのか 悪い行為なのかわかりづらい。 全てのiteratorでconst_castのオーバーロード関数を 用意してくれてると良かった。 つーか誰かSTLに詳しい人作ってYO!!STLport用でいいカエラ!
>>84 > iterator i = const_cast< const_iterator >( ci );
これ、何がしたいの?
> const_castのオーバーロード関数
これも意味がわからん。
>>85 const_cast< iterator >( ci );
これの間違い。
>> const_castのオーバーロード関数
>これも意味がわからん。
これこれ。
template< typename T0, typename T1 >
T1 const_cast( T0 );
template< >
std::set::iterator const_cast< std::set::const_iterator, std::set::iterator >( std::set::const_iterator i ){ ...}
これが全コンテナにあったら便利じゃん。
間違った、C++の仕様に合わせるとこうか。うぜー template< typename T > T const_cast( std::set::const_iterator i ); template< > std::set::iterator const_cast< std::set::iterator >( std::set::const_iterator i ){ ...}
iteratorをmutableメンバ変数として持たなければならない時とか
>>89 mutable iterator って宣言すればいいだけじゃない?
const_cast の出番がわからん。
>>90 class test
{
std::list<int> c;
mutable std::list<int>::iterator i;
void constant_method() const
{
i= c.begin(); // ERROR
i= const_cast< std::list<int>* >(&c)->begin(); // OK
}
void nonconstant_method()
{
i= c.begin(); // OK
}
};
>>92 説明不足ですまんね。
>>86-87 があれば
>>91 みたいな方法とらずに
いいなーみたいな。それだけ。
まあ、あったらイイナ♪(マイメロふう)程度のもの
なんで真に必要な場面はそうないんじゃない?
こういうのがあればいいんだろ
template <class InputIterator1, class InputIterator 2, class OutputIterator>
void copy(InputIterator1 first, Inputiterator2 last, OutputIterator out);
>>86-87 みたいなのは、あってもいいけど
紛らわしいから名前を変えた方がいいよね。
const_cast とはやってることが全然違うし。
const_iterator_cast とかなんとか。
そういうのがあると、beginとendの型が全く違っててもパラメタがマッチするから バグの原因だよなあ 結局解決策は、iteratorの種類ごとにcopyの多重定義ぐらいしかなさげ
>>95 std::iterator_traits + boost::enable_if
あたりを使えばなんとなるっしょ。
どのくらい制限すればいいかは、議論の余地が大有りだろうけど。
97 :
デフォルトの名無しさん :2005/06/05(日) 15:37:17
インスタンス化による拒否だと実装の深い部分で弾かれるのが若干嫌なので
interoperable iterator + enable_if(もしくはconcept check)というのが最良ですかね.
後,最近iterator, const_iterator間のinteroperability以外に
iterationの情報をiteratorの型にエンコードしてコンパイル時にalgorithmをアンロールする
とか,それと普通のiteratorによるループを融合しようという趣旨の話もちらほらあるので
(Fusionとか最近David Abrahamsがやっているヤツとか)
その関連でも
>>94 の形が今後ちらほら出てくるかも知れないです.
void foo(const string& cstr) { string str = cstr; ・・・ copy(str.begin(), cstr.end(), dest); こんなエラーが検出できなくなるのが、ちと気になる。
>>99 現状でも↓がコンパイルエラーにならないんで、何が悪くなるとも思わん。
copy(a.end(), b.end(), dest)
101 :
100 :2005/06/05(日) 15:58:30
copy(a.begin(), b.end(), dest)
102 :
デフォルトの名無しさん :2005/07/23(土) 15:26:07
>>80-82 copy(it, vector<int>::const_iterator(v.end()), dest);はどう?ちょっと長ったらしいけど。
103 :
デフォルトの名無しさん :2005/12/09(金) 23:17:02
boost::shared_ptrのget() を無効にしたいのだけど なにかいい方法あります。
>>104 boostの中の人を恐喝して、get()を取り消させる。
あっそ
>>102 copy(boost::const_begin(v), boost::const_end(v), dest);
で、結局、お前らにとってboostって何よ?
事実上の標準。
ちゅうか、次期標準採用が見込まれるライブラリだろ。 ま、永遠の次期標準ってのも珍しくない業界だけどな。
次期標準なら、俺は標準になってから使う。
俺は標準化されていない今でも使う。 実際俺にとっては有ると便利ではなく、無いと不便と化している。
もはやC++とはboostのことだよ。 MPLのソースなんてどうみてもコンパイラの実装の一部
MPLてなに?
だめだこりゃ
STLが標準じゃないの?
いやつまりSTLがあるんだからいらねーじゃんって話
>>118 STLとBoostは排他的な存在ではないです。
BoostにはたしかにSTLの補完的なものもありますが、
そうでないものもかなり多いです。
排他的も何もboostって、stlなしで動くとは到底思えんが
Boostがなきゃ、最近の言語に作業効率で負けるよ。
123 :
デフォルトの名無しさん :2006/03/29(水) 10:39:49
いや、次要るから。
[要らない理由]
STLは規格により明確にC++である
C++相談室と分けるほどトラフィックもない(ってか閑散としてる)
もし分けるとなるとC++相談室では「C++からSTLを除いたもの」を主な話題とすることになるが
「C++からSTLを除いたもの」でそんなに話題あるかい?
>>127 要る理由は?
それを言い出すとBOOSTスレもいらなくならない?
C++相談室であつかうSTLは純粋な文法のみ STLスレではコンパイラやライブラリによる 実装依存なものまで含んだディープな話題 てなかんじだと私は思っていました。
>>131 >コンパイラやライブラリによる実装依存なものまで含んだディープな話題
のスレの名に「STL相談室」はないだろうw
STL相談室が出来た経緯
【C++】STL(Standard Template Library)相談室
http://pc5.2ch.net/test/read.cgi/tech/1095583235/ よりコピペ
8 名前:デフォルトの名無しさん :04/09/19 20:32:58
STLはSTLで分けてほしい。
でないとBoostまで一体化になってしまう。
9 名前:デフォルトの名無しさん :04/09/20 05:21:12
個人的には、STLだけでも分厚い本がかけるぐらい広大なものだから、STL専用スレがあってもいいとおもうよ。
10 名前:デフォルトの名無しさん :04/09/20 08:25:11
でもtemplateスレは他のC++スレより書き込み少なめだからそこでSTLも済ませてもいいと思うけど。
11 名前:デフォルトの名無しさん :04/09/20 12:11:52
STLもBoostもtemplateの応用例の一部に過ぎないから。
そんなものがtemplateスレを埋めたら
PerlスレをCGIの話で埋めるようなもの。
>>128 もし必要とされてないならスレは1000まで埋まらないっつの
半年でスレ1個埋まるんだからこの板ならまあまあのスピードだ
決して閑散としてた訳じゃないと思うが?
というか必死になってるのは君1人か、多くて君ともう1人だろ?
>>134 同意。ぜんぜん閑散としてない。
なぜそんなに必死にまとめようとしているのかわからん。
ヒルズ脳
ヒルズにいるとまとめようとしたくなるん?
C++相談室とC++凖標準ライブラリってカテゴライズする案があったかな
>>134 ,135
閑散としてないのはたぶんC++相談室でSTLの話もされてるからだと思う.
今までうまくいっているものを変える必要はない。
>>141 だったらSTLスレも要らないということになるぞ。
だったらお前の存在も要らないということになるぞ。
つか廃止はともかくSTLスレっつう名前はなんとかしない? おまいらC++相談室でSTLの話題が出ようものならスレ違ってんで STLスレの方に誘導できるのか? STLスレって名前を単に存続させたいやつはやってみろよ
146 :
145 :2006/03/29(水) 20:52:06
なんなら俺がやってもいいよ
STL使って落とし穴作れるんですか?
STLってさ、ちびまるこの花輪くんが、OTLってしてるみたいだよな
>>145 STLなどという意味のない単語そのものの廃止を提案する。
俺専用テンプレートライブラリ
154 :
デフォルトの名無しさん :2006/08/02(水) 18:46:25
オナニー ツール リスト
オブジェクトテンプレートライブラリ?
157 :
デフォルトの名無しさん :2006/10/14(土) 15:25:22
age
158 :
名無しさん@お腹いっぱい。 :2006/10/14(土) 16:21:20
159 :
デフォルトの名無しさん :2006/10/14(土) 19:28:48
age
すでに次スレが建てられている。
おお知らなかった。
ho
164 :
age :2007/03/15(木) 14:41:54
age
165 :
デフォルトの名無しさん :2007/04/01(日) 15:51:25
valarrayのresizeって vectorのそれと挙動が違うのな。 valarrayはSTLじゃないし、文句は言えないんだけど これにはやられたよ。 皆さんは知ってました?
知らないで使うなんてありえないな。
最近のゆとりは 使う前にざっと実装覗いてみる程度もしねーのか…
「昔のゆとり」という括りがあるのか?
「昔のゆとり」は、スレが立った日時も直前のレスの日付も無視して 沈んでるスレに能書きたれて悦に入るらしいよ。
ゆとりどうしなんだからみんななかよくしろよー
171 :
デフォルトの名無しさん :2007/06/07(木) 20:54:19
ゆとり〜 ゆとり〜 お〜れ〜もぉぉ ゆとり〜
ゆとりゆとりって煽ってるやつて、ゆとり教育が昭和何年から始ったか知らないで言ってるんだろうな。 もしくはすごいおっさんか。
円周率三桁教育受けた世代の事をそれの一つ前の世代が馬鹿にする意味で言ってるんだと思ってた
受験戦争時代より後を、一般的にゆとりと言われてるんだろう。
175 :
デフォルトの名無しさん :2007/06/21(木) 18:25:59
ゆとり教育世代でしょ
エロゲー世代じゃね?
>>145 本屋さんでは、書名にSTLを含めたものも有るし、「ああ、入門書の次の段階の話で
Boostの手前のレベル辺りを話題にすればいいんだな。」と分かり易いし、
ステパノフに敬意を表したいから、伝統ある用語"STL"を残したいな。
ちょっとお聞きしたいのだが typedef struct tagTestData { int num; std::queue<int> que } TestData とかやって TestData *ptr = malloc(sizeof(UserData)) ptr->que.push(1) とやると,プログラムが落ちるのだが,これってnewじゃないと だめ? STLってコンストラクタとか使ってるの? すごい馬鹿な質問でごめん
>>178 その前に、TestData *ptr = malloc(sizeof(UserData))ってことはエラーになるわけだが。
つーか、TestDataかUserDataかどっちなのかと。
queのコンストラクタ呼び出しが行われておらんな
C++でmalloc使っちゃ駄目だろ
>>182 typedef struct tagTestData {
なんて書き出してるあたり、
>>178 はCでそれなりに経験積んだC++移行中の人なのではないかな。
>>178 C++でmallocは禁じ手だよ。
むしろ存在を忘れてしまっても構わない。
C++でもmalloc使ってるおれが来ましたよ
どうやって管理すんのさ。間違ってfreeしたらあぼんしないか? ひょっとしたらハンガリアン? nwepほげほげ mlcpほげほげ あ、これなら徹底すればいけるかもしれないw
コンストラクタ呼ばれないから駄目絶対
そんなにダメだったなんてしらなんだ(((( ;゚Д゚))))
>>186 メモリ空間だけ確保しておいて、ナカミはAPIが格納するオブジェクトかも……
あ、ちゃんとカプセル化すればいいのか
TestData *ptr = (TestData *)operator new(sizeof(TestData)); new (ptr) TestData();
素直にnewできない〜 勇気を私にください〜
184じゃないけど、バイナリファイルを読み込むときに new char [] は不自然かと思い、malloc() を使ってる。 テキストファイルのときは new char []。
>>191 STLあるんだからfstream使えば?
mallocつこてるやつはSTL(テンプレートとクラスの固まりだが)とクラスにmemsetもしてないだろうな
>>191 だから、そういう目的のためにoperator newがあるんだろうに。
mallocとの違いは、不足時に例外を出すかどうかだけだよ。実質的に。
STLのvectorの実装でも、内部ではoperator newでブロック確保して使ってる。
(古いものに備えて)malloc使ってるのももちろんあるけど。
>>191 んなもんスタックのバッファに確保するかvector<>使えよ
んなところでいちいちmalloc()やnewなんぞ使うな
明示的なdeleteやfreeは恥だと思え
>>183 > Cでそれなりに経験積んだC++移行中の人
おれには、Cの教科書でC++のコーディングしてるプログラミング初級者にしか見えない。
>>179 も書いているけど、”UserData”がなんなのか分からないと、
質問の意図がどこにあるのかすら分からない。
197 :
191 :2007/09/17(月) 14:56:09
>>194 なるほど。次回からそうする。
>>192 ,195
型を char とか unsigned char とかにするのが気に入らないと言っているのだが、読み取ってはくれなかった?
typedef unsigned char byte; としておけば済むことじゃないの?
#include <boost/cstdint.hpp> using boost::uint8_t;
allocaは遅い
Mr.malloc よりは速くね?
205 :
デフォルトの名無しさん :2008/01/17(木) 19:47:05
>>172 > ゆとりゆとりって煽ってるやつて、ゆとり教育が昭和何年から始ったか知らないで言ってるんだろうな。
> もしくはすごいおっさんか。
>
団塊世代とは中高年の総称である。
○ or ×?
>>205 ゆとり教育とは戦後教育のすべててある
教育勅語で教育を受けていない香具師をゆとりという
まぁ教育勅語で育った世代が少年だった頃は、 強盗強姦殺人、いずれも今の少年の数倍やらかしてたんだけどね。 多少のゆとりはあったほうがいいな。
戦後教育ならGHQ教育と呼ぶべきかも ゆとりはむしろ極左系の影響を受けてる印象がある
まあ、どっちにしても愚民化政策という点で一致してる罠
一般的には受験戦争時代より後の、土曜日が授業じゃなくなった 辺りを指すようだな。
今の学生は土曜昼下がりのワクワクっぷりを味わえないのか。
半ドンも死語だしな。
ゆとりっつっても80年代前半くらいまでの生まれは 受験競争が異様に加熱してた時代で育ってんだよなぁ 子供が勉強漬けになってるって、しょっちゅうマスコミが取り上げてた
いまの子供も勉強漬けですよ 学校で教えないから塾に郁子が増えるんだって で政府の発表の方は学校ベースだから それをマスコミュが真に受けて増幅してるだけ
stlやboostは使わなくなった。ソースが汚くなるわ、デバッグは面倒だわ。 まぁ、納品で永遠におさらばの時だけ使ってるwww
あー、漏れも納品で永遠におさらばの時だけstlもboostも使わずに済ませるよ。
stlやboostの代わりに作られたであろう車輪のことを思うとゾッとするわ。
コンテナまで自作か。おそろしく効率悪いことしてるんだな。
lambdaとかsplitとか使っていればそりゃ汚くなるわ。
220 :
デフォルトの名無しさん :2008/03/07(金) 13:12:59
>>220 C++0x では、そこの var に対応する auto が入ることになった。
それが本質的な解決かどうかはともかく、一応C++0xでは、 コンテナに初期化子{a, b, c}が使えるようになり、 自動変数には型推論が使えるようになるはず。
autoって何だかBASICの再来みたいで嫌だな
>>220 アクセサが気に入らねーならクラスにすんなと。
全部publicにして直さわりだと、後で内部構造変えたりできねーじゃん。何のためのprivateメンバなんだと。
まあ、こんなこと無いだろうけど3次元ベクトルをクラス内部で直交座標系で保持してたのを
内部処理の都合で極座標で保持するように変更するとかさ。
アクセス関数経由してたら、内部を変えてもクラス外部からは従来通り、直交座標で値の設定ができるわけでよ。
単に長ったらしいコードが嫌と言っているようにしか見えない。 例えば、C# 3.0の自動プロパティでは、 public int Hoge {get; set;}という風に書ける。こういうのがいいと言っているのでは? 224のように変更する必要が出てきたら、従来の書き方に変えればいい。
>>224 あんなアクセサ作る奴は内部構造変えたらそれに合わせてアクセサも追加したり
しかねない。
>>225 そもそもクラスの発想は再利用だろ(俺自身は全然再利用できてねーけど)。
クラスを作る人間と使う人間が別々の場合を想定して作るべきじゃん。
使う人間に内部構造を意識させたら負けでしょ。
setterはアンチパターンだから ダメなコードは書きにくくするという点でJavaは正しい
自動プロパティはJavaにも導入すべきだと思うけど、C++には導入しないでほしいな リファクタリング支援環境に乏しい言語だとかえって足枷になる
230 :
デフォルトの名無しさん :2008/03/10(月) 11:03:43
STLって何がめんどーなんだろうかと思ったんだが、 バッファリングやってくれないからクラスっぽくないんだよね。 クラスっぽくないから、メソッド足し難い。
誰か翻訳してくれ。
クラスっぽくない=継承せずにそのまま使うことが前提になっている(普通の利用者については) かな? バッファリングやってくれない、のほうは分からん。 頭痛が痛いのかもしれない。
継承しなけりゃクラスじゃないってのはそりゃ違うけどな。 Facade パターンみたいに継承しない使い方も定番の使い方だ。
>>230 STLにメソッド足し難いってどういう意味?
例えばvectorに追加機能が欲しいけどメンバ関数が追加できないって言いたいのか?
そういう場合はランダムアクセスイテレータに適用可能なアルゴリズムを書けばおk。
それはvector以外のコンテナにも利用可能な汎用メソッドとなる。
>>234 というSTLのやり方に230が慣れていないだけだと思う。
派生クラスじゃなくてコンテナアダプタを作る方法もあるな
for_eachの実装を見て、あまりの単純さにびっくりしたとかよくあることだし
ほとんど普通のwhileループに見えるからな。 その分イテレータとファンクタが頑張ってるんだが。
> バッファリングやってくれない、のほうは分からん。 > 頭痛が痛いのかもしれない。 やべえじわじわ来た
ふつーにメンバ関数足したいじゃん。 だって、そうでないと理解してくれない利用者もいるわけだし。 イテレータンのことを知らない人も居るんだおw
vectorのpush_backと[]演算子しか使ってない俺にはiteratorなんぞ不要
>>241 甘いな、そこまで言うならpush_back()ではなくコンストラクタでサイズを決めてしまえw
それだったら尚のことグローバル関数を追加すればいいと思ってしまう。
>尚のこと で、 何で、 >グローバル関数 グローバルという最悪解がでるんだよ。 がいきち?
>>244 単なる誤爆じゃないのか? いくらなんでもそんな素っ頓狂なこと、気が違っていたってしないだろ。
なんか興奮気味のお馬鹿さんが来たね
>>244 俺はvectorを継承してメンバ関数を追加するより
vectorを引数に取るグローバル関数を追加するほうがまだマシだと思っている。
五十歩百歩とか言うなら、そりゃそのとおりだ。
>>247 五十歩百歩じゃねーよ。
クラスにメソッド足すのはふつー。
グローバル関数サイアク。
>>248 vector限定ではなくなるけど、<algorithm>の関数群はサイアクなのか?
>>249 ライブラリとして存在する関数と、
今からコードを足すのに関数しかできん、というのとは比較しているものが違う。
池沼、氏ね。
>>250 ライブラリは別ですか。
じゃあ話は変わるけど、Effecitve C++の2版19項あるいは3版23項で、
メンバ関数よりも非メンバ関数が勧められていることはどう思う?
開発にはC言語よりはC++なだけで、 C++の推奨に純粋に従っていく気はさらさらありません。 開発するもののデザインを正しくしたいだけ。 STLも開発者の要望になびくべき。
アホの要望になびいてもしょうがないかも。
>グローバル関数を追加すればいいと思ってしまう。 ↑ アホ
>>252 お前とC++で正しいデザインの方向性が違うように思える。
(俺じゃなくてC++なのは、俺とC++もまた方向性が違うと感じるときがあるから)
>>253 アホの要望でもそれが多数派なら従うべきだね。
自分は多数派と思い込んでるあたりがアホ。
↑ 完全誤読のアホ。
> 完全誤読 そんな四字熟語はありません。
>>258 漢字が四つ並べばすべて四字熟語だと思っていませんか?
# 「完全誤読」が妥当かどうかは兎も角。
では何故、いきなり>258のようなことを言い出したのですか?
>>261 「では」ではなく「だから」ですね。
もし私が「漢字が4つ並べばすべて四字熟語だと思っている」のなら、
「漢字が4つ並んでいるのに四字熟語ではない」という事態は私の考える世界にはあり得ないはずであり、
「完全誤読」の4文字を見た瞬間、私はそれを「そういう四字熟語」だと思ったはずですが、
私は「そんな四字熟語は存在しない」と言っているわけです。
つまり、漢字が4つ並べばすべて四字熟語だとは思っていないから出てきたものに対して、
あなたは(あなたですよね?)「漢字が四つ並べばすべて四字熟語だと思っていませんか?」と問うたわけです。
完全無駄……じゃなくて、完全に無駄な質問ですね。
噛み付くことに意味を見出しているんだから 当人には無駄ではなくて君にだけ無駄なんだ
265 :
257 :2008/03/18(火) 08:38:08
残念でした。 257以降にはレスしません。 つまり、264の言葉は264にしか該当しませんw
>257以降にはレスしません。 257より後にはレスしていません、でした。
>>261 は「何故そのような当たり前の指摘をするのか」を問うているように見えるんですが
もしその通りなら
>>263 は答えになっていませんし、随分間抜けな印象ですね。
>完全無駄……じゃなくて、完全に無駄な質問ですね。 なら、 >常考……じゃなくて、常識で考えて とか、 >がいしゅつ・・・じゃなくて、既出ですね。 とでもいうのか? ウザウザ。
>>268 「完全無駄」っていうのが、常考やがいしゅつのような「用語」なら、お前の言ってることも一理ある。
でもこの場合、単に日本語がおかしいだけだから、馬鹿にされてもしょうがない。
さらに言うと、お前のその的外れな切り返しも、「完全無駄」と同じくらい馬鹿にされてもしょうがない。ばーかw
>常考やがいしゅつのような これらだって、出た瞬間は、 >単に日本語がおかしいだけだから だったんだお。 おまいが全てを仕切るな、消えろ。
ばーかw ワロタ
272=完全馬鹿
>>271 どっちも出た瞬間は馬鹿にされまくってたじゃん。そして今回も馬鹿にされている。
噛み付きたかったら、「完全誤読」が充分に流行って、「今さら2ch語にマジ突っ込みかよ!」
って言える空気がこの言葉に関して醸成されてからにしてちょーだい。間抜けなヒステリーは勘弁。
あと、たぶんお前、「仕切る」の意味をどっかで勘違いしてるぞ。
自分の意見をいくら言っても、正しい日本語をいくら紹介しても、それは仕切るとは言わない。
全体の流れ等を統制するために、他人の意見をさえぎったり、無理矢理な話題転換を強制するのが
「仕切り」で、それはお前がいま「消えろ」という言葉でやったことだ。
要するにお前が仕切ってるわけ。間抜けなヒステリーは勘弁。
次の次あたりで、どう言い返していいかわからなくなって シャボン玉のように壊れて消えると予想。
あきれて、華麗にスルーw
vectorなどのコンテナを継承して 新しいコンテナを作ったことがあるけど いちいち数あるコンストラクタを再定義しなければならなかったのが きつかったな。ここら辺がC#とか新しい言語でも同じなんかな?
STL のコンテナは仮想デストラクタ持ってないから public 継承は危険だな。 protected/private 継承ならマシではあるが。 まあそれはおいといて、コンストラクタはどうしようもないと思う。
vectorを継承したところで 新コンテナの実装にvector使っているだけで大部分の関数が再定義ってことになるから、 単に包含でよくね? 新コンテナとvectorに親子関係もたせる必要性って多分ないでしょ。
まあ、メソッド追加したかった、ってことはあると思うけどね。
STLコンテナとかイテレータとかって、直接つかうんじゃなくて もうすこし高レベルのクラスを実装するのに使うのが正しいんじゃないのかと。 部品を作る部品、みたいな。
282 :
277 :2008/03/19(水) 23:11:18
俺が作ったのは、selectionというvectorをpublic継承したクラスで 単純に、配列の中で、現在選択されている要素を示す機能を追加したものだった。 (ドロップダウンリストで使うようなイメージ) これを実現する為だけに、vectorの殆どのメソッドを再定義しなければなかった。 継承というアプローチが間違っていたんだろうか。
>>279 が、そのものずばり言っていたか。
正直すまんこかるかった
意見かぶるけど、自分ならよっぽどの場合じゃなけゃvectorなどの普通手を入れない部品は継承しないな。包含にする。 継承するならリスコフの置換原則を守ってるかチェックした方がよいかと。
>>278 protected/private 継承でもvectorのデストラクタは呼ばれないから関係ないのでは?
っていうか仮想デストラクタ持ってないクラスは 暗黙的に継承禁止ってことなんだね・・。早く言ってよ。 class Derived : public Base { virtual ~Derived(){ Base::~Base();} }; でも、継承する場合でも、とりあえずこうしておけばOKなのかなぁ?
>>285 仮想デストラクタがないことの問題は、アップキャストされた状態でdeleteされたときに、
正しいデストラクタが呼ばれないこと。
逆にデストラクタが呼ばれるときにインスタンスの正しい型が判っていれば、
例え仮想でなくてもきちんとデストラクタは呼ばれる。
これに関するprotected/private継承の利点は、クラスの外で自由にアップキャストできないので、
デストラクタが正しく呼ばれない心配が大きく緩和されるということ。
>>286 だからそれも無意味。
>>286 色々と全ての点で駄目すぎる。
まず、Derivedのデストラクタが呼ばれるときは、
自動的にBaseのデストラクタも呼び出されるから明示的にベースクラスのデストラクタを呼ぶ必要はない。
また、Baseクラスが仮想デストラクタでないならDerivedクラスで仮想デストラクタを定義しても意味はない。
(Derivedクラスからさらに継承する場合でdelete時にBaseクラスを介さないときを除く)
ちなみに仮想デストラクタがない=継承禁止ではない。
多くの場合、public仮想デストラクタかprotected 非仮想デストラクタが継承を認める場合の書き方。
前者はdelete時にもBaseクラスを使う場合、後者はdelete時にはDerivedクラスを使う場合に使う。
実験的にVectorの要素のクラスの コピーコンストラクタとデストラクタで 動作ログ吐き出すようにしてみたら 異常にコピー&破棄繰り返しててワロス
>>289 前もってreserveすればある程度は抑えられるかもしれない。
291 :
278 :2008/03/20(木) 12:05:50
>>285 >逆にデストラクタが呼ばれるときにインスタンスの正しい型が判っていれば、
>例え仮想でなくてもきちんとデストラクタは呼ばれる。
ごめん。そのとおりだった。ここを勘違いしていた。それと、呼ばれないのはvectorのデストラクタではなく、
派生クラスのデストラクタの間違いだった。
>>288 なるほど。後者のケースは知らなかったので勉強になった。デストラクタをprotectedにしておけば
Baseをdeleteできないから非仮想デストラクタでいいわけね。でもあえて非仮想にする必要はある?
仮想にしておけばいい気がするんだけど。まさか仮想関数ポインタの4バイト節約じゃないよね?
仮想関数呼び出しのオーバーヘッドが許容できない場合など。
あまりないと思うけどなあ。そんなクリティカルなら継承自体使えない気が。 まあvirtualにする必要がなければしないにこしたことはないね。
294 :
293 :2008/03/20(木) 12:21:51
よく考えればdeleteはしなくてもBaseクラスにアップキャストしてポリモーフィズムすることは可能なわけで、 その場合は仮想関数呼び出しになるな。 まあ 仮想デストラクタがない=継承禁止ではない。 という例として勉強になった。 今までは継承元クラスのデストラクタは必ず仮想でなければいけないと思っていたから。
C++ Coding Standardsだとstd::unary_functionやstd::binary_functionに protectedな非仮想のデストラクタを持たせるべきだったと取り上げている。 あとはCRTPのように、継承はするけど仮想関数を全く使わない場合にも protected非仮想デストラクタの出番だと思う。
unary_functionとbinary_functionにデストラクタ欲しいね。
C++ Coding Standards を 読んだ。一回読んだけど頭に入ってなかったな。 新たな発見だったのは、非仮想publicデストラクタでdeleteした場合の動作は未定義だそうだ。
派生クラス突っ込んでるのに delete した場合、じゃないの?
そう。流れ的に省略した。
300 :
デフォルトの名無しさん :2008/04/04(金) 13:22:26
すみません、アプリでメモリリークが起きてるっぽいんですが、 クラス変数にvectorの実態宣言があってinsertやった場合も、 クラスが破棄されたらvectorは自動でメモリ解放してくれますよね? まさか明示的にresize(0)する必要は無いですよね? (逆にvectorがポインタ宣言だったら、そのポインタの指す実態をdeleteする必要があるだけですよね?)
>>300 そのvectorに何を入れてるの?
オブジェクトを入れてるのならいいけど、オブジェクトへのポインタを入れてるのだったら自分で中身を消さないとダメだよ。
そしてそういう時には boost::ptr_vector が使える
実態宣言?
お前を嫁にもらう前に逝っておきたいことgirl
かなりきびしい話もするが 俺の本音を聴いてOK
俺より先に寝てはいけnight
さだようく?
俺より後に起きてもいけnine
めしは上手くつくlay
dequeの良さに今頃気づきました
いつも綺麗でin low
dequeる範囲で
かまわないcolor
314 :
304 :2008/04/22(火) 22:05:21
俺のせいで流れが・・・ 忘れてくrail nut
She got more deck in night at corny
Cation marmoreal
おまえら何をstring
Has not niter caught on.
319 :
デフォルトの名無しさん :2008/05/16(金) 15:56:34
流れ分断してすまない。 193>> struct Test { vector<int> aaa; vector<string> bbb; int ccc; }; Test test; memset(&test,0,sizeof(Test)); ってSTLつきの構造体をmemsetやったら危険ですか?
>>319 ったり前。
Test test; // メンバ aaa と bbb のコンストラクタが呼び出される
memset(&test,0,sizeof(Test)); // ぶっ壊される
memsetは要はドーザーで更地にするようなもんだからな。 PODはただの区画で、C++クラスは家付き不動産て感じか。
すると、vtblつきのクラスは動産だな。
増築可能に作った不動産じゃね?
324 :
319 :2008/05/19(月) 12:19:47
レスサンクス。 vtblつきのクラスはともかく、 C言語な構造体のvectorは問題ないと思ってmemsetしてた。 一見問題なく動くから困る。今から直します。
処理系で違うだろうけど、vectorの初期値が全部0(NULL)のもあるかもな。
しかし初期値0の場合でも、値入れてからmemsetしちゃったらメモリリークするからな
>>324 そもそもstringはあんたの言う「C言語な構造体」には該当しないと思うのだが。
328 :
319 :2008/05/19(月) 19:05:30
>>327 あいまいな表現で申し訳ない。
aaaのmemsetはセーフだけど
bbbは不味いだろという指摘を期待して質問してしまいました。
「C言語な構造体」というのはPOD型構造体のつもり。
専門用語の厳密な知識が足りないので、あいまいな表現を選択しました。
(aaaをPOD型構造体にしておけばより良かったか)
>>328 vector<int>もvector<string>もPODではない。
ゆえにTestもPODにならない。
330 :
319 :2008/05/21(水) 12:11:22
>>329 了解。
C++の仕様をまともに読んだことがなかったから、読んでみるよ。
図書館で『C++ランゲージ クイックリファレンス』借りてきた。
もう memset(), memcpy() 見ただけで妖気アンテナが立つぜ。
俺は、なんというか、久しぶりに清々しい気分になっちったな〜
>>330 あれはいい参考になるからいつも手元においてる。
ただ、リファレンスのはずなのに、たまにコーディングスタイルに属する問題がさらっと並んで書かれてたりするから注意が必要だけどな。
参考までに、
なんで
>>319 が、vector<int>をPODだと思ってたのかを知りたいな。
336 :
319 :2008/05/23(金) 15:53:40
>>334 おお。しっかり参考にしようと思います。
>>335 一言で言えば無知。
便利そうなものはろくに勉強せずすぐ使ってしまうのがあるかな。
(最初にvector使ったときは便利さに衝撃を受けた)
PODの概念は319の書き込む前後にネットで調べるまで知らなかったです。
vector<int> aaa;
aaa.clear();
size_t size=sizeof(aaa);//20
size=aaa.size();//0(ちなみに)
今思えば、
一度でもこういうコードを試して見れば
memsetが危険かどうか判断できたな。
VC++2005で上記のaaaをウォッチすると
aaa [0]()
このように出るから、int以外でメモリ取ってるイメージが湧かなかった。
よってmemsetもOKかなという判断をしたのだろう。
337 :
319 :2008/05/23(金) 15:56:24
すれ汚しすまん。 ついでに、フローだとこんな感じかな。 こういう後輩がいたらしっかり指導してやってください。 動くプログラムを書けるようになる ↓ 変数は必ず初期化するようにしなさいと言われる ↓ memsetの存在を知る(まとめて初期化できるからこれは便利) ↓ STLを使ってみる(これは便利!) ↓ STLとmemsetの併用が何か怪しい気がした ↓ 質問して悲鳴をあげられた←いまここ
>>337 >STLとmemsetの併用が何か怪しい気がした
いいセンスしてるじゃん!がんがれ〜
std::fillかstd::fill_nを使ってmemsetは禁止するのが良い。 それで大体困らないし。
なるほど コンパイラにエラーを吐かせるようにするわけか
vector<POD> v で memset(&v[0], …)って気持悪いとかそういうこと以外に実害あったっけ?
v.size()が0の時があるので気をつける。
>>341 POD にポインタや不動小数点数が入ってると意味を成さない。 vector 関係ないな。
std::fill ってちゃんと memset 並に最適化されるのん?
組み込み型に対して memset に dispatch する実装もありますけれど, ユーザ定義の POD に対してそれができる実装は見たことない
それは見識が狭いだけかと。
ispodって最近のgccやvcにはあるんだっけ?
VC++は2005から持っている。 ただ、2005も2008もstd::fillでは使われていない。 ただの特殊化で(signed/unsigned) charだけmemsetを呼ぶ実装になっている。
なあ? 素人質問でもうしわけないんだけどさ 中でnewやってるクラス(MyClass)を vector <MyClass> mMy; ってやってpush_backとかresizeすると newしたものってバグる? つまり、何を気にしているかというと push_backやresizeをしたときにクラス1回破棄して作り直してね? ってことナンすけど・・・
STLのコンテナに載せる要件に、コピーコンストラクタが必要、というのがありますが 当然、コンパイラが自動的に作るコピーコンストラクタがどんな動作をするかには言及しませんね。
>>353 >STLのコンテナに載せる要件に、コピーコンストラクタが必要、というのがありますが
マジですか?
んじゃ基本的には
vector <MyClass*> mMy;
みたいにしないといけないの?
コピーコンストラクタがない場合
デフォルトコンストラクタでnewしてコピーコンストラクタで適切にケアして無いのが異常。 そんなクラスを収容できるようにはコンテナはできてないということ。
>>355 え?コピーコンストラクタを実装するのって暗に当たり前だって言ってる?
悪いけど俺にそんな認識はないなぁ・・・つか無かったなぁ
エラーもでないし
はぁ・・・わかりにく・・・これだからテンプレートって使わない人多いんだろうなぁ・・・
ってちょっと思った
>>356 「中でnewやってるクラス」という言葉の意味が、常識的に解釈できる通りの意味だとすると、
これはテンプレートとは全然関係の無い話だよ。
むしろC++の基礎知識に属するというか、マジな話、君は致命的な欠陥のあるクラスを
作りまくってることになるよ・・・。
>>357 マジで?
中でnewってのは
MyClassのメンバ変数にこんなのがあったとして
int *mUnko;
MyClassクラスのどっかで
mUnko = new int[256];
とかやってるってことだよ
これをやってるクラス(MyClass)をvectorでpush_backとかresizeをやると
newで確保した内容が吹き飛んでしまう
って現象
俺はこれ知らんかったなぁ・・・
コピーコンストラクタが定義されてないクラス全部欠陥品ってこと?
メンバに生ポインタ持つなら 自前の代入演算子とコピーコンストラクタは必須だろう それ以外の場合はケースバイケースかな メンバの全てについて、コピーコンストラクタ・代入演算子の呼び出しを考慮してあるなら デフォルトのでいい 面倒ならとりあえずprivateにしてみるのがよい class Hoge { private: Hoge(const Hoge&); Hoge& operator=(const Hoge&); //・・・ }; コンパイルしてエラーが出たら実装。 g++を使っているなら -Weffc++ というマゾっぽいオプションもある。素人にはお勧めできない。
>>359 面倒臭すぎる
つか、絶対に知らない奴多いと思うんだよね
この現象
vector <MyClass*> mMy;
もうクラスをvectorするときはポインタだけに絞ろう
・・・寒気がしてきたZE
> vector <MyClass*> mMy; 中に入っているMyClass*をdeleteし忘れるんですね、わかります
>>356 まぁテンプレートやSTL以前にC++そのものがわかりにくいってことだ。
とりあえずEffective C++ / Effective STL読んどけ。
>>352 みたいなことに自分で気づけたのなら筋はいいと思うな。
vector < shared_ptr<MyClass> > mMy; これなら安全ちゃう?
「現象」として捉えるんですね すごく遠目からみるんですね 「中でnewするクラス」の人は さすがです
そもそも、newしていることに疑問を持たない方がおかしい。
本人は最後まで「vectorに格納する場合に生じる現象」として捉えていたけど、 MyClass hoge, fuga; hoge = fuga; だけでも、なんか素敵なことが起きかねないよな、現状のスキルだと。
MyClass hogehoge(); fugafuga() { MyClass a = hoeghoge(); } 最適化によって落ちたり落ちなかったりするんですね
ここにいる奴ら、std::auto_ptrをコンテナに入れてはいけない 理由を理解してなさそう
370 :
デフォルトの名無しさん :2008/08/31(日) 13:39:26
バカな理屈で周りがバカばっかに見える、二次成長期におなじみの例の病気では。
>>359 今の現場のコーディング規約と同じだー。
> コピーを考慮しないクラスでは、
> コピーコンストラクタと代入演算子をprivateにすること
ってのがあるよ。
厨二病か
クラス内部でnew/deleteをするクラスはコピーコンストラクタと 代入演算子は必須だろうが
>>356 > え?コピーコンストラクタを実装するのって暗に当たり前だって言ってる?
常識というか、普通に気づくんじゃないかね。自前でコピーコンストラクタ書く時に
「あれ?こんなこと自動ではやってくれないよな?」ってのに気づけば。だから
>>359 > 面倒ならとりあえずprivateにしてみるのがよい
とか
>>371 > コピーを考慮しないクラスでは、
> コピーコンストラクタと代入演算子をprivateにすること
とかだし、google のコーディング規約でも↓みたいなマクロが用意されてるわけだ。
// A macro to disallow the copy constructor and operator= functions
// This should be used in the private: declarations for a class
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
class Foo {
public:
Foo(int f);
~Foo();
private:
DISALLOW_COPY_AND_ASSIGN(Foo);
};
>>364 > vector < shared_ptr<MyClass> > mMy;
> これなら安全ちゃう?
shared_ptr<> はオーバヘッドが馬鹿にならないからなぁ。
boost::noncopyable
なんでもshared_ptrにつっこめば解決すると思うな。 自分でコピーコンストラクタと代入演算子を定義して ptr_vector当たりを使うのが正道だ。
>>377 ptr_vector使うならコピーコンストラクタいらないんじゃ…
これ、vectorテンプレートを作った奴の評価としてはNGだろ? 現状そうなってるから仕方ないってのは受け入れた上での評価だけど だってこんな仕様にしたらMyClassを変更するたびに MyClassの仕様として正しい正しくないの他に MyClassを使用している箇所を片っ端から探して newを使用していいかどうか確かめなきゃいけないってことだろ? 最悪じゃね? カプセル化が完全に死んでるじゃん
>>379 何度も言われているが、これは vector じゃなくて C++ 一般の話。
>>380 俺はそうは思わないな
vectorの仕様によっては助かるように細工することもできるわけだし
使用者がvectorの内部まで知らないと使えないってのはやっぱりわかりにくいと思うよ
っていうかコピーコンストラクタの用意されて無いクラスを
vectorにぶち込んだ時点でエラーでもいいと思うけどね
newが使ってあるクラスでコピーコンストラクタが 実装してあることをチェックしてからしかvectorには突っ込めないとか使い難いな
>>383 > vectorの仕様によっては助かるように細工することもできるわけだし
どうやって?
コピーコンストラクタの用意されてないクラスをエラーにすると、 C の構造体が
vector に入れられない。それは面倒だ。
ところでmallocだとどうなんの? アドレスだけコピーしてくれてセーフ? なんてことはないか
>>385 クラスがきたときだけptr_vector仕様にする
>>385 クラスはクラス用のvectorを作って
vectorにクラスを入れるとエラーでもよかったけどね
なにも全部ひっくるめてvectorとかする意味わからないな
そのせいでわかりにくくなるならクラスはクラス用のvectorみたいなのを使う
って決めてあったほうがよかった
と俺は思う
(今のvectorを変えろとかそういう意見じゃなくて今後そういうテンプレート的なものがあったときに
そういうふうに作るようにしたほうがいいんじゃねぇの?ってことな)
>>387 生半可な知識でくだらないこと書きなさんな。C++のclassはstructとはprivateかpublicかの違いしかない。
>>388 あんたが一人でその、「クラス専用ベクタ」とやらを作って使えばいいだろ。
>>389 現状、明らかに使いにくいしわかりにくいのに
そこの改善より
俺が馬鹿で終了?
意味不明
じゃ、仮に中でnewしてても死なないvectorがあったら
現状のvectorとどっち使うの?お前
>>387-388 vector に入れたときだけ大丈夫で >367-368 はやっぱりダメとか、ありえんだろ。
>>392 それはやってみるか中みないとわからんと思うな
ちなみに
>>367 ってエラーでなかったっけ?
中で死なないvectorの為に(それ以外の理由の方が大きいが) 代入とは別に移動(move)という処理を標準化しようという動きはあったろ。 いつになるか分からんけど
>>391 > 仮に中でnewしてても死なないvectorがあったら
listでよくね?
listって確か要素を追加・削除しても、関係ない要素のコピーは起きないよな?
あとC++0xにemplaceが入れば満足か?
>>394 C++0x の move な。一応次の標準に入る予定。
ただ、その場合もコピーと同様に、クラス側で「移動」用の定義を与えないと働かない。
標準ライブラリ内のクラスが move に対応するんで、自動的に大丈夫になる
ケースもあるだろうけど。
つーかこんな挙動、絶対わかんねーって。マジクソだな。
要は、危険なクラスをコンテナだけが安全に使えても意味がないということなんだが。 何でそんな簡単なことも判らないでこのスレにいるんだ?
>>399 えー意味わからん
危険なクラスってコピーコンストラクタがないクラスを言ってるの?
すべてのクラスをvectorに突っ込んでも大丈夫なように作るなんてありえんわ 面倒臭すぎる 職場の超百得ナイフクラスをサポートできへん
>>400 必要なコピーコンストラクタを欠いているクラスが危険だと言っている。
いや、要件を満たしていないのに使えてしまうのが危険なんだよ。
>>402 ?
意味分からん
>要は、危険なクラスをコンテナだけが安全に使えても意味がないということなんだが。
この発言だと
vectorにつっこんだときのことを言ってるんじゃなくて
MyClassが危険なクラスって言いたいんだよね?
でも
>必要なコピーコンストラクタを欠いているクラスが危険だと言っている。
こんなこというからさっぱりわからないよ
何が言いたいの?
>>403 俺もそう思うな
望ましい状態は2つあって使えないような作りか、使えるような作りかだと思うんだよね
405 :
402 :2008/08/31(日) 17:01:04
>>404 vector につっこめないクラスは単体の代入やコピーでも同様の問題を起こすということ。
このようなクラスを安全に代入やコピーをするには、コピーコンストラクタや代入演算子の
定義が必要。そして、それらを定義すれば vector に入れても問題なくなる。
>>404 安全側に倒したいんなら new するポインタの保持に生ポインタを使わないことだ。
int の配列を持つなら vector<int> を使えばいい。
でもvectorだと生ポの6倍程度のメモリを使うんだぜ?
自分で管理できない馬鹿には少ないコストだろ。
>>408 6倍はないだろ。どんなコンパイラでどうやって測った?
>>410 VC9でsizeof(std::vector<int>)で30が返ったんだが。
(20だったかも)
>>411 10個突っ込んでも、300とか200にはならんと思うけど。
size() * sizeof(int) + Nbyteがせいぜいでない?
>>411 4バイトアラインのはずだから、20だろうな。それにしても >412 の言うとおり、
int を256個も入れりゃ気にならんだろ。
>>403 きっと0xならMyClassはCopyConstractableでないしAssignableでもないから
std::vectorに入れられないってエラーになる。
CopyConstructible
>>414 デフォルトの定義で動いちゃうから、無理でしょ。
>>412-413 もちろんvector1つくらいの管理変数サイズを気にしたりはしない。
vector<vector>みたいな状況が怖いわけで。
大量に使うクラスで、生ポで済むのにvector組み込む場合ね。
vectorよりはshared_ptr使った方がいくらかマシか?
>>417 そんなにリソースをキツキツで使いたいならコピーコンストラクタと代入演算子ぐらい
さくっと定義して使えよ。
安全性と効率のトレードオフだ。 C++ ではデフォルトで効率を取るのが言語の方針ってこと。
>>417 コピーコンストラクタとか定義しないいけないのが嫌だから生ポインタじゃ済まないんだろ。
おとなしく vector 使っとけ。
いやだからvectorよりshared_ptrのほうが(ry あるいはもっと向いてるポインタ格納クラスがあればな
>>417 > vector<vector>みたいな状況
おれなら、その状況では管理サイズよりpush_back時の時間の方が気になるけど。
管理サイズが気にならないわけではないよ?
たとえかも知れんけど、listにしとかね?
dequeをですね
窓から投げ捨ててですね
最初にvectorにポインタ入れてクソ仕様と騒いでたヤツはバカだが、 STLコンテナがmoveするべきところをcopyで済ましてるのは、確かに 今となってはまずい設計だったよな。 移動用のファンクタを渡せるようにするなどの対応をするべきだった。
>>424 そういう問題ではない。普通に代入とか、関数に渡すために仮引数に
書いてコピーコンストラクタが呼び出される事実はSTLとは全く関係が
ないにも関わらず同じ問題を引き起こす。
>>425 いや、コピーコンストラクタが不備だったりコピー禁止にし忘れてるクラスの問題の
話ではなく、vectorが再配置にコピー動作を行ってることによって発生する
オーバーヘッドを指摘してるんだよ。
ポインタで配列を保持するようなクラスだと、再配置のときまでコピー動作じゃまずいだろと。
よくわからんけどrealloc()とかの関数を見習った 歴史的経緯があるんじゃないだろうか?
寝ぼけてたようなので補足 >ポインタで配列を保持するようなクラスだと ポインタで配列を保持してるのを、vectorに入れ替えたクラスだと、 再配置のたびvectorの中身までコピーされてオーバーヘッドが大きい。
まぁ、そういう場合は再配置が起き難いように事前に確保しておくからあんまり困らないね。 再配置による中身のコピーのオーバヘッドが気になるくらいなら、真面目にデータ構造見直すし。
うんまぁそういう解決方法もあるけど、移動用の ファンクタなりなんなり設定できると便利だよね。 可変長なデータ読み込む場合とか、最後まで読んで みないと要素数が分からない場合もあるんだし。
作るとか作らないとかそういう話じゃないだろ…
きっと0xならなんとかしてくれるんだよね?
boostにでも提案突撃して来い
あれ? 0x の話ならここで move が出てくる場面じゃ?
長文だが結局あまり実がないので適当にスルーよろ。
現行範囲内で考えるなら swap をできる限り利用する、みたいな
感じになるのかね。
ってことからちょっと考えてみた。
いくつかのアルゴリズムについては swap あるいは iter_swap で
挙動が定義されている。
が、g++ 3.4.4 の libstdc++ の実装では iter_swap は swap を
呼び出さず、また、アルゴリズムで swap と iter_swap を意識して
使い分けているようには見えない。
もちろん swap と(iterator 経由の)iter_swap で結果が異なる
なんてのは論外だけど、swap については独自の型についても
特殊化を提供しよう、みたいな事が言われるが、iter_swap まで
特殊化を提供はしないわけで(っていうか事実上無理)。
結果として、CopyConstructible と Assignable から想定される
swap の一般的な実装 T t(a); a = b; b = t; よりも効率的な swap
を持つ型に対する場合で、かつ、アルゴリズムの実装が iter_swap を
用いる場合には効率が落ちるケースがある、ということになりそう?
って、長々書いてきたけど、
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#187 に既にあったわ。
ということで、0x になると iter_swap が swap で定義されるので上記
問題はなし、ってことのよう。
>>437 "move" とか "move semantics" とか 「右辺値参照」 ("rvalue reference") あたりの
単語で検索していろいろあさってもらえれば恐らく期待しているものが引っかかるかと.
ちなみに swap を使う場合, swap 先 (移動する先) のオブジェクトを
あらかじめ構築していないといけないので,そういうオブジェクトを構築する
汎用の構文 (とその挙動) も規定しないといけないです.
>438 うん。だからあえて「現行範囲内で」。 で、n2738 見ると、vector の insert が軒並み requires MoveAssignable<T> になってるんで (resize は insert と erase で定義されるから resize とかも) 424 辺りが望む挙動を期待していいってことでOK?
追記。 vector 全体が requires MoveConstructible<T> になってる。
LWG187 は iter_swap の元々の動機付けだった, proxy を どうするのかの問題についての立ち位置が分からないですね,これ. move は現行の範囲内でやるならおっしゃるとおり swap でやるのが良いとは思いますけれど (Boost の sand-box にあるエミュレーションもそういう形態を取ってましたし) ただ,現行でやるのは本当に面倒だと思いますよ. N2738 というか, move の proposal の動機付けの1つに, 当然コンテナ内のバッファ再配置があったわけで, 424さんとかの望むことそのものはできないとさすがにまずいかと. 後,あまり関係ないですけれど, N2738 を読む限り,要素型に対する CopyAssignable の要求は必要な箇所のみに完全に絞られるようになりますね.
肛門をいじりすぎたせいでSTL。
>>442 proxy を用いる iterator (iter_swap が本来問題にしていた状況) に関しては,
その LWG742 がそのまま該当すると思います.仮に LWG742 の proposal が通るならば,
iter_swap に関しては swap への単純な委譲 (LWG187 の proposal の通り) で良いかと.
ただ,そこでも指摘されていますけれど, LWG742 のやり方は swap が
template 定義内で unqualified call されることを前提としているわけで,
そうすると異なる2つの型に対する swap の呼び出しによって,
異なる2つの associated namespace の swap の定義が ADL によって
visible になるような状況があるのがまずいだろうな,とは思いますけれど.
日本語でおk
なんか出来損ないの翻訳を読んでいるようだ
無理やり変換しないで訳がわからない単語が残してあるところは 性能がいいのか悪いのか判断しかねるな
ぶっちゃけこんな会話になっちゃうところがもうユーザビリティ最悪だよな このテンプレート
そろそろどこかのブログに 「444は僕です」 と書かれる頃かな
基本的にstl関連使うと 解読不能なほど長いunko.unko.unko.unko.・・・住所はなんとかならんのか 日本の埼玉県鴻巣市吹上3丁目1の4の3の○○マンション306号・・・みたいなw もうわかったよw長いよw 絶望的にセンスねぇよw いくら時代が進んだからってエディタの横幅一杯まで攻めてる理由ないってw
っstlfilt
concept
>>451-452 んで、問題を解決しようとすると
そういう新ワードが出てきてますますわからなくなるんだよなw
そのクラス(テンプレート?)わかる奴一体世のプログラマに何人いんだよって話ですよ
STLfilt一回使ってみろよ マジ感激すっから Perlをインストールする必要があるけど
せめて、コンパイラのエラーメッセージとかで デフォルトテンプレート引数を使用している部分は(スイッチで)省略できるとかなら もうすこし読みやすくなるんだろうけどね。 あと、typedefしてる部分とかも。 ただの引数の型の部分でstd::basic_string<char, std::char_traits<char>, std::allocator<char> > とか。 まあ書く側としてhoge<hage,hige>::iteratorとかになっちゃうのは typedefくらいしかどうしようもないけど。
>>453 ついていけないなら、むりせずやめてもいいんだよ?
>>457 もうわかりやすさとか除外して
ひたすら言語の「できること」探しがはじまったら
言語の存在意義が不明になってしまうで
言語ってのは昔から制限をかけることで進化してきたもんなんだぜ
アセンブラのが色んなことできるぜ型縛りもなんにもないしね
人にわかりやすく、誰でも読めるように、
たくさんの人が簡単に理解できるように
これを忘れた時点でもう何をやっても自己満足でしかない
よう分からんけどC++使わない方がいいよ、きっと
>>459 言語に機能を求めるならアセンブラのがいいよってことだよ
馬鹿だからわかんないかw
うんそうだね。俺もアセンブラ使うよ
また自分の馬鹿さ加減を棚にあげてSTLのせいにするアホウが一人
Lispは自己満足ですか?
464 :
デフォルトの名無しさん :2008/09/21(日) 08:28:09
vector ってデストラクタが vertual じゃないけど 継承するなってこと?
465 :
464 :2008/09/21(日) 08:29:20
間違えた virtual
>>465 基本的に標準ライブラリのクラスはどれも継承するな。
していいのはstreambufくらい。
exceptionは継承してもいいんじゃない?
468 :
464 :2008/09/21(日) 23:48:31
俺みたいな初心者にはこれは落とし穴だね
うん、俺言い過ぎたな。 コンテナクラスは継承するなぐらいに言っておけばよかった。
どんまい。
std::unary_functionとかあるしね
STLportのbasic_string::assign(const CharT*, size_type)って lengthチェックしてるからデータがヌル終端でないと死ぬんだな… デバッグ版のみだけど。
デストラクタがvirtualじゃないvectorを継承すると どういう落とし穴にはまるんですか?
474 :
デフォルトの名無しさん :2008/10/16(木) 00:32:34
>>473 アフォですか?
デストrラクターが呼ばれないと
メモリの開放がされないのでリークして
オーvバーフローするくらい気付け
#include <iostream> class Base { public: ~Base() { std::cout << "~Base" << std::endl; } }; class Derived: public Base { public: ~Derived() { std::cout << "~Derived" << std::endl; } }; int main() { Base * p = new Derived; delete p; return EXIT_SUCCESS; }
Base が vector だよね? じゃあさ、こうは? #include <iostream> class Base { public: ~Base() { std::cout << "~Base" << std::endl; } }; class A { public: virtual ~A() { std::cout << "~A" << std::endl; } }; class Derived: public Base, public A { public: virtual ~Derived() { std::cout << "~Derived" << std::endl; } }; int main() { A* p = new Derived; delete p; return EXIT_SUCCESS; }
>>473-476 未定義動作。結果がどうなるか知りたければ試してみるしかないし、
やってみても何も起こらないかもしれないし、いつも同じ結果になるとも限らない。
まさか
>>473 別に vector に限った事じゃねぇだろに。
Effective C++ 読むなり
「デストラクタ virtual」でググるなりしろ。
>>474 もちつけ。つか、ちゃんと理解してる?
オーバーフローはしないと思う
474はつまらない釣りでしょ
参考文献 C++ Coding Standards 第35項「基本クラスとして設計されていないクラスからは継承しない」 派生クラスのオブジェクトに対して基本クラスの非virtualなデストラクターを呼ぶと未定義動作。
>>477 いやいや476の例は問題ないだろ。
もちろん、それで問題を防げるわけではないから
やっちゃ駄目という結論に変わりはないが。
いつまでこのつまんない話続けるつもり?
>>484 ほほう、貴方が面白い話題を提供してくれるわけか
つまらない話ですいませんでした
487 :
477 :2008/10/17(金) 01:08:14
STL標準講座って本を読んだら rbegin()は末尾を返すって書いてあった。 嘘だった。 すごい落とし穴にはまった。
>>488 末尾だと思うけどねぇ。end()と同じじゃないけど。
remove()は要素を削除するって書いてあった 嘘だった size()取ったらremove()前と後で変わってないよ
end()は最後の要素のひとつ後、従って、*end()は実行時エラー。 Exceptional C++ にもそう書いてある。 一方、rbegin()は最後の要素、だから、*rbegin()は最後の要素を返す。 STL標準講座はその辺ごっちゃだよね。 範囲をあらわす言葉が統一されないだけ。 初心者向けの本だから、最後の要素がひとつくらいcopyされなかったりしても 気にするなよ
誰でも間違いぐらいあるさ 人間だもの みつを
エピの本は買わない これ常識
えぴタンのが間違ってるとして、rend()って何が返るって言えばいいのかな。 先頭の直前を指すイテレータ?
逆方向に考えて、末尾の次。
逆方向の末尾は順方向の先頭?
そりゃそうだ。
もちろんrend()を逆参照すると未定義の動作
size()が1以上なら、begin()[0]とrend()[-1]は同じ。
それは保証されてない。
知ったかは去ればーか
[ begin, end ) [ rbegin, rend ) なわけだけど、 そもそもこの半分開いた範囲の話すら出てこないのがSTL標準講座。 begin から end に向かって到達可能であることが推定されることも説明されてない。 何より、Visual C++ ver.6 で動作確認という まったく標準 C++ に準拠していない実装依存なコードが満載。
仕様とか無知なくせにふと思ったんだが、STLってスレッドセーフ? 今は一応クリティカルセクション作って保護してあるが、イラナイなら面倒だからはずしたい・・・
C++の規格としては今のところ何も決まっていないから、 自分の使っている奴の説明書読め。
509 :
507 :2008/12/15(月) 19:55:50
あーSTL使うとC#より遅くなる。 辛いねー
んなこたーない。使い方が悪いんだろ。 コード貼ってもらえるといいんだが。
_SECURE_SCL
きっとDebugビルドになっているとかで最適化していないのだろ。
いろんな意味で使い方を間違っていれば、C#より遅くなっても不思議ではないと思うけどな。 不必要にコピーを連発しているとか、インライン化が阻害される書き方をしているとか。
漏れは
>>510 はきっとポインタじゃなくて実体を格納させて
コピーコンストラクタが走り回ってると見るけど、
>>514 以外に考えられる原因ってある?
どうでもいい。エスパースレでやれ。
いや簡単なソースを書いてみろよ。 C#の方が大抵はやいんだよ。 俺は気がついた時、正直死ぬほど驚いた。
>>517 「簡単なソース」をさ晒してみてくれよ。
>>518 バイナリリードでフロートを三時限配列に代入。
アレイつかったプラプラはシャープの倍以上かかる。
試してミソ。
どうせvectorの領域再確保が発生してるだけでしょ
バイナリリードってどうせoperator>>を使ったんだろ fread()使ってみろよ絶対にC++の方が早いから それからC#にはシリアライズ機能が標準装備されているから 比較するならC++もboost使って比較しろ
C#の方がデフォルトで楽に速度が出るってことでいいかな。 fread?それCじゃん。C++と比較するならstreamじゃないと。
C++でもread()つかってストリームバッファ入力すると速いと思うぞ
比較するならプログラム出して検証可能にしてくれ
このままだと
>>519 がアホチンなことをしてる可能性が否定できない
(というか、そうとしか思えない)
>C#の方がデフォルトで楽に速度が出るってことでいいかな。 その認識でいいと思う しかし、必要とあらばそこだけCやアセンブリで書いて 手軽に最適化ができるというのもC++の強みかと
つまりC++/CLI最強と。
ストリームの読み書きの速度で言語の速度を比較するスレはここですか?
そう読み違えている人がいるスレならここですよ。
なら、速度を欲する目的にiostreamやC#という選択をする人が居るスレがここですね。
いや、初心者にありがちな「C++ではstdioは使うべきではない」と考える人のスレです。 それと、write()やReadFileのようなシステムコールを直接呼び出す方が速くなると 勘違いしている初心者のスレでもあります。 「とにかくアセンブラにすれば速い」と思ってそうな気配のある人もいるかもしれません。
話はガラッと変わるが、 C#もLINQ登場で一気に魅力的になった。ラムダ式もC++0xより先行しているし。
でも一番短かく書けるラムダ式ってboost::lambdaなんだよなぁ… 短さだけが正義じゃないけどさ
コンパイル時間の長さもboost::lambdaが一番だな
C++はさすがに古いから他言語に乗り換えたくもあるけど、 用途的に無理だからなあ
ネイティブコンパイルしてくれて GC によるストップザワールドのない言語となると C/C++ くらいしか選択肢ないしな。
>>532 bindなんかが必要になったら一巻の終わりだよ。
そうならない限りは本当にいいんだけどね。
bindバカにすんなてめぇ
バカはバカだろ
バインドはバカじゃないよ。単にラムダから短さを失わせるだけで。 特にメンバへのアクセスが嫌だね。
意味もない機能でデブな言語になってやったぜ!
unko.resize(unko.size()+1); unko[unko.size()-1] = new Unko(); unko[unko.size()-1].init(chinko,manko・・・); return unko[unko.size()-1]; これなんとかなんないの?
Unko *p = new Unko(); p->init(); unko.push_back(p); return p;
そもそもどうしたいのかが分からん。
std::auto_ptr<Unko> ap(new Unko); ap->init(...); unko.push_back(ap.get()); return ap.release();
>>547 いや、だからよ
そういうブロックみたいな塊自体を無くしたいわけよ
push_backがインデックスを返してくれるだけでよかったのにと思ってる
なんか、あんまり実用的ではないなぁー。
>>549 そうなんだよ
push_backがインデックス返すだけじゃ駄目だなw
こんな感じの処理のおかげで結局管理クラス(〜Manage)とか作ったりしねぇ?
上では初期化処理ちょっと省略して書いたけど結局newやinitが失敗したりしたときの
処理まで書くとあんまりvectorやlistに恩恵感じなくなる
>>550 何を問題としてるかよくわからんが、とりあえず vector や list を使わなければ
解決する問題ではないだろ。
もしかして ptr_vector が欲しいってだけか?
何故Unkoにinitがあるのかもわからん コンストラクタで初期化するだろ普通 unko.push_back(new Unko(...)); return unko.back();
>>552 それ、 push_back() で bad_alloc したら Unko が漏れる。
>>553 ホントだよ
だだ漏れだよ
括約筋の切れたアナルとなにも変わらない
reserveで予約しておけば push_backではbad_allocが出ないことが保証されてるけどな。
当然スマートポインタのコンテナだよな? 所有権管理してない生ポインタのコンテナとかありえないよね?
unko.reserve(unko.size()+1); return *(unko.insert(unko.end(), new Unko(...))); これでFAかな。
558 :
557 :2009/02/08(日) 14:48:40
なんか俺、大腸な気がしてきた。
ほんとうは、Unko漏れる 言いたかっただけちゃうんかと
うんこのさいずもうひとつよやくして、うんこのはしにあたらしいうんこをいれてかえす。
>>559 initが要らないなんて言っていないよ。
コンストラクタが内部でinitを呼べればいいと言う話。
コーラック飲んどけって話か
やだよコンストラクタで、大量の初期処理なんて。 キメの細かいエラー処理ができねーじゃん。
まあ具体性のない話を長々としても どうせ解決するわけがないわな。
next_permutationって重複してる値があったらうまく並び替えてくれないんだな
質問があります。 たとえば、Windows APIとSTLの組み合わせとして、 以下のソース、※1、※2はOKなんでしょうか? ダメ出しと回避策があればお願いします。 (エラー判定など詳細部分は省略) HANDLE hFile; DWORD dwCnt; DWORD dwSize; std::deque<BYTE> d; std::vector<BYTE> v; hFile = ::CreateFile(省略...); dwSize = ::GetFileSize(hFile, NULL); d.resize(dwSize); v.resize(dwSize); ::SetFilePointer(hFile, 0, NULL, FILE_BEGIN); ::ReadFile(hFile, &d[0] , dwSize, &dwCnt, NULL); // ※1 ::SetFilePointer(hFile, 0, NULL, FILE_BEGIN); ::ReadFile(hFile, &v[0] , dwSize, &dwCnt, NULL); // ※2 ::CloseHandle(hFile);
規格によって、連続した論理番地に要素が格納されることが要求される 標準コンテナは vector の方だけ。 なんだけど、そういうことが訊きたかったのかな。 もう少し質問が簡で要を得てるといいんだけど。
569 :
567 :2009/03/05(木) 09:00:41
>>568 dequeにこだわる訳ではないですが、
やっぱろdequeを使うべきではない?
実は、シリアル通信でReadFileを使った例があり
以降の電文解析がdequeだったので、
ReadFileがdequeでいければいいなぁなどなど・・・
1. vector(または配列), deque 間の変換負荷は許容する 2. deque を使った既存コードの利用を諦める どれかを受け入れるしかないんでないの
ソースがあって、pop_front/push_frontを使っていなければ、 そのコード、vectorに変えても使えるのでは、と思う。
573 :
デフォルトの名無しさん :2009/04/01(水) 15:01:28
新規質問です: 今までvectorモンリーで開発してました。 vectorをqueueに差し替えようと思うのですが、 イテレータンでしかアクセスできなくなるんですよね? vector<MY_REC> items; int i = items[index].MY_MEMBER; とか書けなくなるわけですか? どう書き直せば良いのか教えて下さいorz
574 :
573 :2009/04/01(水) 15:12:50
>vectorをqueueに差し替えようと思うのですが、 vectorに近いdequeのが良いみたいですね。
575 :
デフォルトの名無しさん :2009/04/02(木) 14:29:03
dequeってリニアアドレスじゃないけど、 dequer<MY_REC> items; int i = items[index].MY_MEMBER; って書けるんでしたっけ?
>>575 書ける
operator[]があるから
577 :
575 :2009/04/02(木) 15:19:26
dクス C++の演算子のオーバーロードってこういう風に使われてるんですね。 自分では使ったこと無いけど。 逆にポインタ取って[]で書くとアウトなんですね。
std::dequeはリニアである保証がないからな
579 :
575 :2009/04/02(木) 17:04:11
C言語で書いてた時は、memsetとか使いまくりでリニアって重要でしたが、 C++になってからクラスってmemsetできないし(特にstring)、 リニアの重要性って無くなりましたよね。
C++0xを待て
581 :
575 :2009/04/02(木) 17:21:18
>C++0x kwsk リニアのメモリ2つのせいで、 Out of Memoryエラーが発生してて、 vectorイヤンな気分。
std::stringがリニアである事が保証される予定 std::ropeはだめだが
>>579 そんなこといって組んでると、javaより遅いプログラムになるぞ。
つーか、もうなってるんだけどな!
ちょっと便利なアセンブラにちょっと便利な機能付け加えた言語用の ちょっと便利なライブラリって事を忘れちゃダメだよな
しかし、8割はJavaより遅くても問題ない罠(要出典)
>std::stringがリニアである事が保証される予定 stringが構造体のメンバだったりしたらリニアって無理な希ガス? >std::ropeはだめだが はつみみです。今ググってみましたが長い文字列ですか。
>>586 >stringが構造体のメンバだったりしたらリニアって無理な希ガス?
違うvectorと同等にするって意味
std::ropeは非標準だがstd::stringよりカット&ペーストに向いている
vector<MY_REC> items; で、 items.erase(&.items[1]); とかしてたんだけど、 vectorをdequeにしたら、うわ、コンパイルエラー。 eraseの引数はイテレータンなんでつよね。 記述間違ってない希ガスるんだけど。
引数はイテレータなんだから、イテレータを渡そうよ。&items[1] はイテレータではない。 vectorならそれで動くこともあるだろうけど。
591 :
590 :2009/04/03(金) 17:47:32
そうか、自分ベクタタンばっかり使ってたから、 items[?]でイテレーターになると思い込んでいた。 イテレーターの書き方が分からないorz
592 :
589 :2009/04/03(金) 17:49:12
↑ 名前590は589の間違いゴメソ
begin() とか end() とかでイテレータを取得できる。イテレータに ++ を作用させれば前に進む。 イテレータが具体的にどんな型なのかは、利用者は知らなくて良い。 (実際にはただのポインタであることもある。) イレテータの型は vector<MY_REC>::iterator などの名前でtypedefされてるので、必要ならこれを使う。
594 :
589 :2009/04/03(金) 18:03:49
dクス items.erase(items.begin + 1); でコンパイル通りました。 念のため確認したいのは。 dequeはvectorみたく、 ・勝手に順番は変わらない。 ・items.begin + X → X番目の要素を表す であってますよね?
595 :
589 :2009/04/03(金) 18:04:48
>items.erase(items.begin + 1); ごめんなさい、 items.erase(items.begin() + 1); でしたorz
596 :
589 :2009/04/03(金) 18:12:14
最後の連投です、すみません。 vectorの要素のアドレスをイテレーターとして使うのは、どうなんでしょう? a) 意識して使うなら記述的にOK b) アドレス使わず素直にイテレーター使えば? c) イテレーターに比べて間違ってコンパイル通る場合があるので、アドレス使うのやめるべき d) vectorから別に差し替え難いのでやめるべき e) その他
あってる。OK。
>>596 まあ、b)c)かな。たぶん、環境によってはvectorでも
>>589 は通らないことがあると思うよ。
なぜvectorだと通るんだろう ポインタからイテレータに変換されたりするのかな?
>>599 イテレータの実態(実装)が単なるポインタであることがある。
なるほど thx
602 :
589 :2009/04/03(金) 18:47:16
何だか回答が頂けて嬉しい。最後の最後の連投です。 (ポインタ→イレテーター化は直せる数でしたので直すつもり) vectorとdequeの違いに興味が出てきました。 vectorってresizeしてサイズを大きくした場合、 リニアアドレスが取れない場合、 勝手に先頭ポインタ(と亀の子式に残り全部)変わっちゃう場合があるんですよね? (サイズが大きい場合、アプリ固まるんだろうか) それに対してdequeの場合、リニアじゃない分、 要素のポインタは安定して同じ場所に居てくれるのでしょうか? 多分、上記両方とも実装依存なんでしょうけど。 ただ、STLの場合、実装依存でありながら、この操作は短時間で終わる事、 みたいな実装指定に近い規定だった記憶があるのですが。(ネットつまみ食いの知識www)
>>602 実装依存じゃないよ。規格にイテレータの扱いも書いてある。
deque は vector よりも厳しい。
例えば、挿入操作は再配置の有無に限らず、
すべてのイテレータと参照を無効にする。
つまりアドレスが変わる。
そもそも reserve すらないし。
>実装依存じゃないよ。規格にイテレータの扱いも書いてある。 あっ、そうなんですか。メモメモ >挿入操作は再配置の有無に限らず、 すべてのイテレータと参照を無効にする。 この文章が知りたかったんです、有難うございます。STLらしい厳格な文章ですね。 STL知らない人にSTLの考え方とか注意点を伝えるとき、 イテレータンとこの1文を言っとけば大きな間違いは無くせる気がします。
23.2.1.3 dequeは末尾か先頭で挿入される限り、全ての反復子が無効になるが参照は無効にならない。 この特性はdequeを使う主要な理由に成り得る。
ちょw
throw NullPointerException
catch(NullPointerException e) { Ga(); }
void Ga() { throw NullPointerException(); }
なるほど、STLって危険なんだねGaクブル
>>610 STL無しに同等の機能を作るコストを考えてみるといいよ
もっと危険でgkbrなコードが生成されると思われる
ハサミも使いようだしなぁ
これってイテレータ無効化される? vector<int> v; transform(v.begin(),v.end(),back_inserter(v),bind1st(plus<int>(),1));
再配置が起これば無効化されるし、 そもそも無限ループ。
あ、無限ループはしてるのはわかるけど 無効化されるのかが気になったので 再配置、ってのは、vectorのcapacityの拡張が起こるかっていうこと? だとするとこの例は必ず無効化されるわけか
関数の引数にvectorの参照を渡して 内部でサイズが変わるような処理したらマズイと どっかで読んだような気がするのですが心当たり有りませんか? void somefunc(vector<string>& data) { data.push_back("hoge"); } 本なら大抵揃ってるので書籍名とページ数だけでも構いません…。 よろしくお願いいたします。
>>616 そのコードは全く問題ない。つーか参照渡して中身をいじれなくてどうするんだよ。
おまいが勘違いしてるのはイテレータのことじゃないか?
618 :
616 :2009/08/01(土) 03:12:50
どうもそのようで。 手元でも普通に動いてたんですが、 アレ、ホントにこれでも良かったかな?と 疑心暗鬼になってました。 レスありがとうございました。
自動焼人 ★ = 自動保守 ◆KAWORUKOFI = 自動保守#K9K?_D[L
名言集 その4
『俺の経歴カックイイだろ?』
http://yutori7.2ch.net/test/read.cgi/news4vip/1249830540/ ID:PVAf+dux0 = 自動焼人 ★
> 984 :以下、名無しにかわりましてVIPがお送りします [sage] :2009/08/10(月) 00:11:14.95 ID:PVAf+dux0
> 俺の簡単な年表(笑)
> 高二秋:自前のパソコンゲット
> 高三春:コテハンとしてデビュー、指揮官見習い
> 高三秋:指揮官デビュー
> 大一:新しい武器の開発や、突撃で数々の戦歴を残す
> 大二春:規制系キャップ取得、第一線から退く
> 大二夏:ネットでのゲーム作成プロジェクト始動
> 大二秋:政治系オフに参加
> 大二冬:最後の突撃、華々しく散る
> 大三春:政治系活動を本格始動
> 大三夏:三度目の選挙へ
>
> おまえらは、後を継ぐなよw
----------------------------------------------
この自動焼人 ★メールマガジンの配信停止をご希望される方は
http://qb5.2ch.net/test/read.cgi/sec2chd/1250169591/ にて自動焼人 ★までご連絡ください
とあるC配列を使っていたコードをvectorに置き換えたんだが・・・ なんかエラーになると思って調べたら、 (以下簡略化したサンプル) int ar[10]; int idx; idx = 5; idx[ar] = 50; となってた→arを要素10個のvectorに置き換えたらエラー。 idx[ar] = 50; なんて書き方ができることを初めて知った・・・
char c = 3["Hello"]; とか余裕〜
やられた p+c-1==v.size()-1のとき copy(v.begin()+p-1,v.begin()+p+c-1,u.begin()); //実行時エラー。p+cの時点でオーバーラン copy(v.begin()+p-1,v.begin()+p-1+c,u.begin()); //OK copy(v.begin()+p-1,v.begin()+(p+c-1),u.begin()); //OK
v.end() + 1
std::listから取得したiteratorって、それが指している先の要素が削除された時以外は 常に同じ要素を指し続けてくれますか? std::vectorとかはころころ変わりますよね
vector<T> イテレータ無効化の罠 で辛酸をなめると、他のコンテナでもビクビクするよな 俺だけかもしれんが
vectorはコピーしまくりになるから 要素の変更がある用途には向かない っつーかvector禁止でも良いくらい
>>628 イテレータでビクビクすることはないが、
生ポインタがあちこちに渡されてるのを見ると不安になる。
631 :
デフォルトの名無しさん :2010/04/16(金) 08:57:18
>>629 使い分けのできないバカのためにメモリ連続が保証されたコンテナを捨てる必要はない。
馬鹿を基準にしちゃうと何一つ安全・確実なものは存在しなくなるからねえ。 フェイルセーフにも限度というものがある。
コンテナの特性なんて最初に全部暗記しておくものだろう と思ったけど要点を細大漏らさず書いてある比較表、一覧ってないのかな。 Effective STLも留意点の全てが載ってるわけじゃないし。
>>633 なんか半年くらい前かな?
STL系でぐぐると一番にヒットしてたサイト。ヒットしなくなったよね
潰れたのかな
あそこが一番わかりやすくて良かったんだが
sumi氏のページのことなら、潰したらしい ついでにboost.cppllも潰れねえかなぁ
>>633 覚える必要なんて無いよ。
必要になってから探せばいい。
目の前の問題に必要なコンテナの特性を理解する能力を磨くのが先。
暗記自慢を増やしても仕方ない。
そんな数ないんだし、使い方はともかく、特性くらいは覚えておいて損はないよ
>>633 STLの仕様書を読めばいいのだ。
コンテナが満たすべき仕様がすべて書いてある。
逆に言えば、書かれていないいかなる仕様も保障されていない。
ちゅか、それがまさにEffective STLに書かれていることなわけだ。
C++エキスパートだけがC++を必要とするわけじゃない。
エキスパートになりたい人は全部読む。 そうじゃない人は必要なとこだけ読めばいい。
C++エキスパートになると頭が禿げます
自分が書いてるコードがどう動くかくらい知っといてね
メンバにstringを追加したクラスをresize(mycls.size()+1)で増やすとプログラムが落ちるんですけど これってやったらダメですか? それとも別のどっかが悪いのでしょうか?
本当にstd::string::resize()を呼んだときに落ちるなら、おそらくメモリ確保に失敗してる mycls.size()の値は確認した?
resizeを実行するインスタンスが何なのか、 myclsが何なのか、どこで実行されているのか、全く分からない もっと具体的に書いてくれ
auto_ptrを使ってみた 意外と使えるじゃんこれ なんでみんな避けてるの?
コンテナにつっこめないから
コンテナに突っ込めないっていうかそれは副作用であって そもそも二つ以上のポインタから参照出来ないっていうのが欠陥
auto_ptr<Hoge> p(new Hoge()); としたあと Hoge *q = p; して Hoge * をコンテナに入れれば良いんでね?
>>649 何の意味があるんだ?
pの寿命が尽きるとコンテナの中身が勝手に消されるぞ。
コンテナを使い終わってからpの寿命が消えればいいんだろ
>>646 別にみんなが避けてるわけじゃない
多くの人はその特性を理解して適切に使ってると思う
ただ、コピーコンストラクタや代入演算子の挙動が異質だったり
色々と仕様の変遷があったり、VCの古いバージョンが不完全だったりしたので
使用に際していくつかの注意点があった
その注意点を理解出来なかったり、理解するのが面倒な人たちが避けてるだけだと思う
auto_ptrが必要なのはreleaseが要るときだけ
>>644-645 レスありがとうございます
リビルドすることで落ちなくはなったんですけど
たしかこれってダメでしたね
完全に忘れていました
このスレの
>>352-から続く話を読んで思い出しました
ああ、長い時間が無駄に・・・
やっちまいました・・・
>>352 と同じ間違いをプログラム全域にわたってやっちまいました・・・orz
vector -> decue
念のため確認しておくけど「間違い」は 「コピーコンストラクタ、代入演算子、デストラクタを適切に定義していなかった」 であって、「resize() を呼んでしまった」じゃないよね?
どうやって適切に定義するの?
確保、コピー、破棄
つーか、コピー操作をするクラスにコピーコンストラクタや代入演算子が必要かどうか判断つかない人がいることが怖い。
>>660 うっかりvectorを使うとすべて必要になるからな
vectorツッコミ禁止コードを入れておけば問題ない
>>661 vectorだけじゃないだろ。
dequeでもポインタじゃなくてオブジェクトを突っ込んだらコピーが発生する。
コピコン禁止コードってあったじゃん 望月ボウヨウ先生の入門書に書いてあった
ちがう 柴田望洋先生だw
privateにコピーコンストラクタや代入演算子を入れる知恵があれば、コピーできないクラスをコピーなんてしないでしょ。
さよならvector <MyClass> mMy;ですね
急にスレ伸びてるけどなんかあったの?
こんにちわvector <MyClass *> mMy;ですね
670 :
child :2010/08/05(木) 17:44:39
visual C++ 2010を使っていて、stlportの設定中で困っています。 詳しい方がいましたら教えていただきたいです。 STLportをビルド・インストールする際に、 configure msvc8でやると2008みたいでコマンドが通りません。 何を入力したらよいでしょうか?
671 :
デフォルトの名無しさん :2010/10/10(日) 20:47:27
STL固有の問題じゃないんだがこのコードが通らねぇ std::set<void(Class::*)(int)> methods; methods.insert(&Class::Method); 原因は、メンバー関数は==と!=以外の比較ができないから。 これ欠陥じゃね?
>>671 メンバ関数へのポインタに限らず、普通関数へのポインタなんかコンテナに入れないだろ
>>672 それが必要だったりするんだよ。
こういうのを作ってたんだがな。
BroadCaster<void(Event&)> mouse_down;
Controler ctrl;
Event e;
mouse_down.Attach(Delegate<void(Event&)>(&ctrl,&Controler::NextClick); //リスナー登録
mouse_down(e); //すべてのリスナーにイベント発行
これの内部でsetを使ってる。でDelegateを一意に識別するためには、
どうしてもメンバー関数を内部で比較する必要があるんだよ。
まぁ、この例が特異だとしても、イベントリスナーをsetに突っ込むなんてよくやりそうな事じゃ
ないか?
>>673 だとすればメンバ関数が==と!=しか使えないのはC++の仕様であって、バグではない
ましてやstd::setの責任でもない
設計ミスとしか言いようがないな
>>673 お前はメンバ関数へのポインタを基礎からやり直せ
>>674 じゃ、コンテナに突っ込む必要がある時君ならどうする?
関数をコンテナから除去するときvectorに突っ込んで全部なめて削除するのか?
それがC++の仕様だからと言って。
>>676 だからコンテナに突っ込む事そのものが間違いだと言っているんだ
std::auto_ptrをコンテナに突っ込むのが間違いなのと同じだ
>>675 理屈は解ってんだよ。実行するまで本当の関数が特定できないから、
メンバー関数のポインターは普通のポインターじゃない。それは解ってる。
しかし、一度なんらかの関数が代入が代入されると言うことは一意に関数を
識別できるってことではある。現に、関数ポインターを(long**)(&mp):として
とりだしてやれば一意の値を取り出すことも可能なんだ。だから、本来言語仕様で
制限するような事じゃないはずだろ。
>>678 だったらここでいくら吠えても無駄だよ
C++標準化委員会に言いな
基本的には仕様書に従え
ここではこれしか言えん
>>678 メンバ関数へのポインタじゃなくて、メンバに別のint型のプライオリティフラグでも持って、
それで叙述関数か何か書いてsetに叩き込めばいいだろう
いくらでも回避策はあるはずだ
頭の固いやっちゃな
>>680 具体的にどうやんの?頭固いから解んないわ。
>>673 みたいな例だったら、似たようなことをやっているはずのBoost.Signals2のソースに、参考になるとこないかなあ?
>>681 例えば生成パターンにクラスを生成させて、フラグにはそれで連番振るの
それでソートさせるとかすりゃいいじゃん
==と!=ができるのだから、常に固定値を返す最悪なハッシュ関数と共にunordered_setに突っ込むという手も考えられる。 やりたくはないけど。
>>682 >>673 の例は結局メンバー関数の関数部をポインターに変換して計算してるから
いまさら別にいいんだけどね。
stlコンテナを使ったときの汎用的な方法が知りたいよ。
>>684 うおっバリバリのboostプログラミング
見た目C#みたいだな
>>689 それlとrそのもののアドレス比較してて、何を入れようと結果変わらず、
意味なくね?
>>691 汚ねーテクニック使ってるなおい
移植性ないだろ
ないよ
>>691 は苦し紛れなりに頑張ってるのではw
一意の識別子をkeyに持ってvalueに関数を保持しているのなら見た事あるよ
vectorに保持するのを否定してるみたいだけど、
そんなに速度差が出るほど大量にコールバックを格納するのかな
ポインタ同士の等値以外の比較は未定義じゃなかったかな。 あとreinterpret_cast使え。
同じ配列に属さないアドレス同士の比較結果は不定、か。
intptr_t があるじゃん。 もう大抵の処理系で使えるんじゃないの? template<> struct std::less<void(Class::*)(int)> : public std::binary_function <void(Class::*)(int), void(Class::*)(int), bool> { bool operator()( void(Class::*_Left)(int) , void(Class::*_Right)(int) ) const { return *reinterpret_cast<intptr_t*>(&_Left) < *reinterpret_cast<intptr_t*>(&_Right); } }; 不定といったって、実行時に変化するわけじゃないでしょ。 大小関係が実行時に一定なら、この用途には充分。 一定じゃない実装も考えうるけど。
まあでも、普通のポインタなら、p == qなら、(intptr_t)p == (intptr_t)qも保証されているので、 心配なら、整数に変換してから比較する比較子を作ってもいいし、 整数に変換した値をハッシュ値にしてunordered_setに入れるのなら、なんの心配も要らないはず。 メンバへのポインタだとそんな保証はあったっけ?
>>697 メンバ関数へのポインタはintptr_tと同じ大きさとは限らない。
仮想関数なんかに対処しないといけないため。
少なくともsizeofで見ないとダメだよ。
g++ (x86 32ビット)だとintptr_tの倍の8バイト、
VC++ (x86 32ビット)もコンパイルオプションやその他状況次第で4から最大16バイトになる。
intptr_t 及び void * は データ型へのポインタについてしか、相互変換での安全性は保証されていない。 メンバ関数に限らず、通常の関数ポインタもダメ。
汎用的な関数ポインタコンテナはID変換式にするしかないのか
だからお前ら規格で保証されてない事を無理にしようとすんなって
>>703 というより、そもそも、どうしてそれが保証されると思うのかが聞きたいw
ところで
>>680 のいうint型のプライオリティフラグを持たせる方法とやらはどうやるのかね?
質問よろしいでしょうか std::fstreamを使ってバイナリデータを読み込もうとしています。 データは、いくつもの構造体をそのままダンプしたデータとなっており ---- fstrm.exceptions(std::fstream::badbit | std::fstream::failbit); fstrm.open("hoeg.dat", (std::ios::in | std::ios::binary)); fstream.read(&hogeStruct, sizeof(hogeStruct)); fstream.read(&fooStruct, sizeof(fooStruct)); ---- こんな感じで次々構造体にreadしていこうと思いました。 ここで困ったのですが、どうも「readした結果、ぴったりファイル終末まで達したら」failでExceptionが投げられるようなのです。 期待していたのは「readなりで、ファイルサイズをオーバーして読もうとしたら」例外。 という挙動なのですが、こちらはfstreamに存在しないのでしょうか? eofのExceptionも「ぴったりファイル終末まで達したら」投げられてしまうようでして…。
707 :
706 :2010/10/19(火) 14:28:52
>>706 すいません、こちら私の勘違いが原因でした。
ぴったし+1バイト以上読むとeofbitのExceptionおよびfailbitのExceptionが発生しました。
こちらのテストコードミスです。すいませんでした
boo-----
tes
710 :
デフォルトの名無しさん :2010/11/29(月) 15:52:26
最近寂しいのでageますよ
711 :
デフォルトの名無しさん :2010/12/03(金) 18:21:05
streamの例外はbadbitだけ立てると使いやすいよね
failbit も立てとかないと中途半端じゃないか?
確かにstd::iostreamは例外で処理すると綺麗に書けるな
理由が解らんでもないんだが、std::mapにconstでoperator[]アクセス出来ないのは 微妙だよなぁ。constで呼び出されたときに未格納のキーを渡されたら例外出せばいいだろうに。
そもそもキーが無い時に勝手に要素追加するという仕様がイケてない
だよね
とはいっても、組込み屋としては例外吐かれても困る。 end() の参照を返すわけにもいくまい。 コンパイルエラーにしてくれる現状がベスト。 だいたいその程度なら自分でユーティリティ作ればいいだろう。
>>718 組み込み屋はなんで例外吐かれると困るの?
どのみち map 使ってたら bad_alloc 飛んでくるんじゃね?
組み込みコンパイラは例外対応が不十分(というかハード的に無理)なんてザラでは
>>719 処理速度やメモリ消費を考慮して例外を使用しない設定でビルドするよ。
STL コンテナを使うときには例外出さない自作アロケータ使うよ。
>>721 処理速度?
例外使っても throw 〜 catch 以外は遅くなるところ無いんじゃないの?
むしろ戻り値でエラーチェックしないぶん速くなることもあるみたいだし。
メモリ消費っていうのはコードサイズのことかな?
RAM の消費は数 KB ってとこだよね?
スタックオブジェクト廃棄のためにtry-catch文を書いたのと同じコードが生成される事はよくある。
>>723 それはあたりまえ。
でも try で処理速度が問題になることは(最近のコンパイラでは)ほぼ無い。
VC6 とか Mingw 3.x.x あたりでは try (およびローカルオブジェクト)ごとに
コードが追加されてえらいことになってたみたいだけど。
>>722 > 例外使っても throw 〜 catch 以外は遅くなるところ無いんじゃないの?
throw 〜 catch 使わないなら例外自体使わなくてもいいでしょ。
メモリはコードサイズとテーブルのサイズ。
実行時に消費するメモリがどのくらいかはちょっと見当がつかない(かなり少ないんじゃないか)。
>>725 >> 例外使っても throw 〜 catch 以外は遅くなるところ無いんじゃないの?
> throw 〜 catch 使わないなら例外自体使わなくてもいいでしょ。
throw 〜 catch をまったく使わないんじゃなくて、 throw 〜 catch が
遅くなるだけならかまわない(異常系の速度を気にしないところでしか
使わない)ってことでしょ。
map の例で言えば、 at() と find()+if とを見つからない場合の速度要求に
応じて使い分けるってことになるね。
なので
>>721 のように「例外を使用しない設定でビルド」する理由に
処理速度を挙げるのはおかしいんじゃないの?って話。
>>726 例外ランタイムをリンクするだけで処理速度にペナルティがあるなんて話をしたつもりはないよ。
728 :
デフォルトの名無しさん :2011/03/23(水) 18:38:31.04
mapのvalue_typeはどうしてconst keyだけなの? キーと値のペアを一時変数でごにょごにょいじって再格納したいときとか、 value_typeを集めたvectorを作りたい時とか困るじゃん! 今は苦肉の策で typedef std::pair<hoge, hoge> mutable_value_type; mutable_value_type pair(hogeMap.begin()->first, hogeMap.begin()->second); とかしてるけど面倒すぎるよ!何か良い方法ないの?
>>728 挿入時と検索時の速度を保証するため
もしconstじゃなかったら挿入の度に木を再構築しなければならず、ものすごく遅くなる
>>728 規格で規定はされてないけど普通木構造で実装するので key の値を変えられると最悪木全体の再構築が必要になる。
key なり pair<key,value> なりにコピーしてから変更すれば?そのコードはちょい遠回りじゃね?
>>728 std::pair<hoge, hoge> hogecopy( *hogeMap.begin() );
std::pair<const hoge, hoge> & hogeref( *hogeMap.begin() );
ていうか、なんで pair にするの?
key を変更して再格納するなら key, value のそれぞれの一時変数を作るのが平明でしょ。
value を編集したり、集めたりするなら、イテレータのままで問題ない。
もしかして型名を書くのが面倒臭いという話だろうか typedef map< ..., ... > mt; typedef pair< remove_const< mt::value_type::first_type >::type, mt::value_type::second_type > mpt; 確かにあんまりイケてない気がする
boost様の力でどうにかならないんすか?
>732 さしあたって mt::value_type::first_type は mt::key_type、mt::value_type::second_type は mt::mapped_type でいける。
map使うときpairも必須なんだから、mt:pairを何で用意してないの?って話じゃね
736 :
デフォルトの名無しさん :2011/04/12(火) 21:00:55.82
vectorへの要素追加と削除時に要素に対して任意の処理を実行したくて、 継承したクラスを作ったんだが、 .erase(std::remove())の記法で削除される要素は、 eraseに来る時点で該当要素のオブジェクトが初期化されてしまっていた。 (具体的には、shared_ptr要素の指す先がnullになっていた) なにか他に良い方法はないだろうか?
継承しないで手作業で呼び出しクラスを書く
sortかstable_sortしてfindしてeraseする
そうか、ごめん完全に頭がやられてる。
removeeraseの使用を禁止して、
代わりにfinderaseベースの削除コードを
使用するよう規定すればいいのか。
>>737-738 ありがとう。
sortする理由は、removeだと詰めて空いた分の要素が初期化されちゃうけど、
sortなら初期化されずに同値が隣接するだけになるからってことで合ってるかな?
削除したいかどうかを基準に比較するファンクタを使ってソートすれば remove同様前後に分かれるだろ
>>736 そのクラスで書き込み可能なイテレータや参照を公開している限り、
任意の処理を漏れなく実行することは無理でしょう。
アロケータという手もあるけど面倒だな
そもそもコンテナって継承していいんだっけ
>>743 継承しても、 new で得たポインタをアップキャストしたまま delete しない限りは問題ない。
745 :
デフォルトの名無しさん :2011/05/26(木) 18:27:34.11
vector<int> v; v.reserve(1000); for(int i=0; i<1000; ++i) v[i]=i; とした後に、 vector<int>::iterator it; for(it=v.begin(); it!=v.end(); ++it) cout<< *it <<endl; としてもうまくいきません。v.end()がv[1000]の次を指していないため ですが、v.end()を設定する方法ってあるんでしょうか? それとも、reserveとiteratorは相性が悪いのでしょうか?
v[i]=i を v.push_back(i) にかえる
確かreserve()は領域を予約するだけで アクセス可能になるわけではないと思いますが
748 :
デフォルトの名無しさん :2011/05/26(木) 21:05:46.19
>>746 そうなんですが・・・ push_backでは時間がかかります。
>>747 実際、reserveしてみると、普通にV[i]=iのアクセスが可能です。
「いや、そう見えるだけであって実際には・・・の話かもしれないけど
(C++では意外なメカニズムに驚くことが多すぎて、自信ないです)。
いや、そう見えるだけであって実際には範囲外アクセス
>>748 [i]が単なるポインタアクセスになってるからできてしまっているが、
reserveしただけの段階だとsize()の値とかend()の返す位置とかpush/pop_back()
など全部変化しないから、色々困るだろう。
[i]で初期値を入れるなら、reserveじゃなくてresizeを使うといいよ。
>>748 あとreserveしたサイズ内でのpush_backならメモリの拡張処理は発生しないと
思うので、時間もかからないんじゃないの。
(どの環境なのか分からないので断言はできないが)
752 :
デフォルトの名無しさん :2011/05/26(木) 22:21:30.30
>>748 そう、難しく考えなくとも
vector<int> v(1000);
で済む話でした。ただ、intを格納するのなら問題ないですが、
自作のオブジェクト、それも引数付きのオブジェクトを格納
するときはreserveが必要なわけで。で
しかし、iteratorは使えないわけで。
>>749 -
>>751 嘘。
>>745 reserve()じゃなくてresize()だろう
ちゃんと規格票か本読め
std::vector<int> vec; vec.reserve(5); for( int i = 0; i < 5; ++i ) vec[i] = i; ↓codepad の g++ でabortした > /usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/debug/vector:192: > error: attempt to subscript container with out-of-bounds index 0, but > container only holds 0 elements. たまたま上手く動いているように見えるだけで reserveしただけの要素に直接アクセスするのはやはり避けるべきでしょう
>>752 reserve() + push_back() でいいだろ。
確かに最終的な要素数が決まっている状況で size() を 1 ずつ増やしていくのは無駄だけど、
自作のオブジェクトならその部分の負荷の割合も下がるだろうし。
reserve()というのはメモリの再割り当てを指定した要素数になるまで起きないように 防止するだけの働きであり、実際に空のコンテナを用意するわけではない だから未定義の動作=鼻から悪魔 メモリの再割り当てが起きると時間が掛かるしイテレータ・ポインタ・参照が無効に なるのでそれを回避したい時に使うがそれ以上の意味はない 詳しくはEffective STL P65を見よう
あ、size()を超えたコンテナへのアクセスとかイテレータの逆参照などが鼻から悪魔ね
758 :
デフォルトの名無しさん :2011/05/27(金) 09:37:17.26
>>749-
>>751 ごめん。俺の間違いだったかもしれん。
>>756 Effective STL P65、ちょっと前に読んだことあるけど、言ってる
ことが俺にはよくわからなかった。空のコンテナを確保しておか
ないと、メモリの再割り当てを防止できないと思うけど。
>>754 そうかもしれない。
>>755 確かに。でも、gcc4.4.2 + SGI STL ? では reserve()を使わずに
vector<int> v;
for(itr=0; itr<itrmax; ++itr) {
for(i=0; i<N; ++i) v1.push_back(i);
v1.clear();
}
とやった方が圧倒的に速かった。STLの実装にもよるがreserve()を使う
ご利益がわからない。iteratorの無効化は防げるだろうけど。
759 :
デフォルトの名無しさん :2011/05/27(金) 09:39:21.11
v1→v
760 :
デフォルトの名無しさん :2011/05/27(金) 09:59:39.02
ごめん。また間違えた。gcc4.4.2 → gcc4.4.1
>>755 比較するベンチマークのプログラムが間違ってた。やはり、
reserve() + push_back()の方が速かった。
(1) reserve()関数で領域確保しても、push_back()で要素を格納していく。
(2) いきなり、[]演算子を使って要素の代入を行うのは危険
ってとこか。しかし、v.reserve(N)を呼び出した時点でv.size()、v.end()
を使えるようにすることはreserve()関数内で可能だと思うが、そうしない
のはなぜだろう?
だからresize()というメンバがあるんだって。 調べろよ
一応書くとreserveはメモリの割り当てのみで コンストラクタが呼ばれない=オブジェクトが初期化されない。 resizeは初期化される=アクセスしても安全。
763 :
デフォルトの名無しさん :2011/05/27(金) 10:24:15.26
resize()はメモリの再割り当てで時間がかかるし、イテレータ が無効になるだろが。知らんくせに横から口出すな。カス!
きみ向いてないよ
こんな過疎スレで釣りするヤツの気が知れない
>>763 それは reserve() も同じだよ。
コンストラクタが呼ばれないということは 当然デストラクタも呼ばれないわけで もはやオブジェクト指向どころの話ではなく charのブロックをnewして直接弄ってるのとあまり変わらない気がするw
>>763 馬鹿かお前は
Effective STLを100回読んでから書き込め
C++関連のスレ荒らしてるいつものアホだから、構っちゃダメ
100冊買ったけど1回も読んでないわ。カス!
771 :
デフォルトの名無しさん :2011/05/27(金) 21:15:21.15
>>768 こういう奴に限って、全然わかっとらんw
>>771 まだ噛みついてんのか
余程悔しかったらしいなw
773 :
デフォルトの名無しさん :2011/05/27(金) 21:38:14.95
いいや、全然。 馬鹿か
なんだ自分の書いてる事のおかしさにも気づけない馬鹿だったか
ID出てないのにくさいって凄い
776 :
デフォルトの名無しさん :2011/05/28(土) 02:55:17.04
うざい。どうでもいい。
STLの本はどれも退屈で刺激がすくない -> non stimulate
すげえな。ここまで頭悪いと笑えるわ。
殆ど自演だからね
780 :
デフォルトの名無しさん :2011/05/28(土) 17:34:58.92
しょうもない奴等ばかりw
たとえそこが肥溜めでも首を突っ込まずにはいられない
落とし穴スレだけに
std::vector<double> Prob(N+1); あqwせdrふじこlp;←適当な処理 Prob[N] = std::accumulate(Prob.begin(), Prob.end()-1, 0); N番目の要素にN-1番目までの要素の和を求めて、 結果が1になるのを確認したかったのですが、Prob[N]に0が代入されました だれか何か御教示ください。
なんでend()の結果を1引いているの?
Pr[0],Pr[1],Pr[2],...Pr[N-1],Pr[N] ↑Pr.begin() ↑Pr.end() となると思ったので、イテレータから-1しました.
ずれた。…orz やりたいことは、 Prob[0]からProb[N-1]までの要素の和を求めて、 Prob[N]に合計を代入したかったんです。
>>783 合計が 0 だったんだろ。 1 になるというのならその根拠がわかるように書いてくれないと。
あqwせdrふじこlp;←適当な処理 は、乱数を割り当てて、その規格化定数で割るといった処理をしているので、 合計は1かそれに近い値になります。 実際に各要素を出力させても、[0,1)の範囲で値が入っているため 合計が0になることはありえません。 STLでは、引数にvectorをとる関数の返り値を、 その引数に代入させてはいけないのか疑問に思ったので 質問させて頂きました
Prob.end()-1がまずいんじゃないの? std::advance(Prob.end(), -1)に置き換えたらどうなる?
std::accumulateの第三引数を 0 から 0. にしろ
0て書くとintと判断されるつまり
>>790 ってこと(ドットがあると浮動小数点数になる)
デバッガで追えば簡単に分かることだからちゃんとデバッグしよう
Prob[N] = std::accumulate<double>(Prob.begin(), Prob.end()-1, 0); ではどうかな?
>>792 累算する値の型はテンプレート第2引数だから、そうはいかない。
・・・それでいけるようにしたほうがよかったんだろうな。設計ミスっぽい。
accumulateの引数の型は、いかにも落とし穴っぽい。 スレの趣旨にぴったりだな。
>>789 合計値は変わりませんでした。
random-access iteratorの演算子に、-が含まれているので
リテラルとして,Pr.end()-1はあっている気がします.
>>790 ,791
ありがとうございます。期待する値を得ることができました
今度からデバッガかけます
§26.4.1 Accumulate 1 Effects: Computes its result by initializing the accumulator acc with the initial value init and then modifies it with acc = acc + *i or acc = binary_op(acc, *i) for every iterator i in the range [first, last) in order.262) 2 Requires: T must meet the requirements of CopyConstructible (20.1.3) and Assignable (23.1) types. binary_op shall not cause side effects. マジだorz >acc = acc + *i or acc = binary_op(acc, *i) for every iterator i in the range つまりaccの型がintだといくらdoubleを足しても小数点以下は切り捨てか
797 :
デフォルトの名無しさん :2011/05/29(日) 17:41:18.40
ほんと、糞みたいなコードありがたがってどういうつもりやらw メイヤーなんて、そりゃプログラミングはわかるかもしれないが、 論理的な思考というか、説明能力が欠如 そんなのをありがたがっている黄色い猿どもってw
798 :
デフォルトの名無しさん :2011/05/29(日) 17:42:58.22
額に「馬鹿」の字が見事にw
連投するぐらいなら一回でまとめようや それとも一つにまとめるよりばらけさせて二倍臭いとかそんなつもり?
>>796 を解決する方法が一つ見つかった
面倒だけど
std::accumulateの宣言は
template <class InputIterator, class T>
T accumulate (InputIterator first, InputIterator last, T init);
だから
int main()
{
std::vector<double> vd;
for (int i = 0; i < 10; i++)
vd.push_back(i);
double sum = std::accumulate<std::vector<double>::iterator, double>(vd.begin(), vd.end(), 0);
std::cout << sum << std::endl;
}
こういう書き方なら末尾の 0 を double と見なしてくれる
std::accumulate(v.begin(), v.end(), static_cast<double>(0)); std::accumulate(v.begin(), v.end(), double()); 型名を明示したかったらこうすればいいだけのことだろ ばかばかしい
>>801 それはわかっている
Generic Template Programmingを読んだらaccumulateの宣言が載っていたので
それでやろうと思っただけ
template引数の使い方も知っておかないとまずい場合もあるだろ
俺だったらこうするね
std::accumulate(v.begin(), v.end(), 0.0);
それより何をそんなに怒っているんだ? >ばかばかしい
怒られてると思うなら精神科による診断をお奨めします
この程度で怒る方がおかしいと思う
>>805 がまだわかっていないようなのでもういちどいいます
怒られてると思うなら精神科による診断をお奨めします
ばかばかしい
808 :
忍法帖【Lv=4,xxxP】 :2011/06/11(土) 13:11:51.79
>>806 理由は?理由も書かずにいきなり「精神科に行け」とは失礼過ぎませんか?
あなたの方がおかしい可能性も十分にあるでしょう
だから理由を聞かせて下さい
>>805 この程度で怒られる事もあるんですよ
「ばかばかしい」という言葉は強い意味ですよ
もしそう思っても書かないで、あなたの腹の中で思ってて下さい
書くと誤解を招きます
だいいち「ばかばかしい」という言葉が余計 自分の非を差し置いて人に「精神科に行け」とはずいぶんな言いがかりですね
Standard Template ばかばかしい
>>812 STLがばかばかしいんじゃなくてお前の頭が馬鹿なだけだろjk
ばかばかしい
ばかばかしいならこのスレに来なきゃいいのに マゾですか?
mapってさ。iteratorがpair返すじゃん。 うんでさ、大抵のalgorithmってfirst、secondに引っかかるじゃん。 みんなどうしてんの? わざわざpair用に噛ませるfunctorとか作ってんの?
>>817 こういう話か?だからC++1xはlambda式が使えるようになってるわけよ
こういう面倒な事をしなくても済むように
struct Pred : public std::unary_function<std::pair<const std::string, int>, bool> {
std::string str;
public:
explicit Pred(const std::string& s) : str(s) {}
result_type operator()(argument_type& pos) const {
return str == pos.first;
}
};
int main()
{
std::map<std::string, int> si;
si["abc"] = 1;
si["def"] = 2;
si["ghi"] = 3;
std::map<std::string, int>::const_iterator pos = std::find_if(si.begin(), si.end(), Pred("def"));
std::cout << pos->second << std::endl;
}
そうそうそういう感じ。 ラムダはともかく、なんでC++03の時点でライブラリのサポートが無いのかわからん。
>>818 それをlambda式を使って書くとどうなるの?
>>820 int main()
{
std::map<const std::string, int> si;
si["abc"] = 1;
si["def"] = 2;
si["ghi"] = 3;
std::map<const std::string, int>::const_iterator pos = std::find_if(si.begin(), si.end(), [&](std::pair<const std::string, int> pos) { return pos.first == "def"; });
std::cout << pos->second << std::endl;
}
どや、無茶苦茶シンプルになるやろ
>>819 え?サポートされてるでしょ
単に関数オブジェクトを勉強すればすぐに理解出来る
ただ unary_function とか binary_function の必要性は関数アダプタを
勉強するまで分からないだろうが
>>821 短くなるけど、[&]ってセンス悪過ぎない?
>>823 俺もC++1xのlambda式はあまりにも見た目が汚いと思うんだが、FDISで誰も
代替案を出せないんだと
多分このまま決まるな
VS2010もg++もこのlambda式が使えるし
inline, inline& がいいと思ったんだけどな。 個別にキャプチャするにはやっぱり囲わないとダメか。
STLのヘッダの中を覗いたら、吐き気がしたわ こんなもん考えたやつ、頭オカシイんでねーの?
>>826 それは甘い
boostのソース見て見ろよ
完全に発狂していると思えるぞ
物によるがboostの方がマクロ乱舞のライブラリよりは大分ましだろ。
( ゚Д゚)ハァ?
vimのquick fixでコンパイルして、エラー箇所としてboostのヘッダファイルに バッファが飛んだとき、将来の職業としてプログラマだけにはなってたまるかって思ったよ
>>826-827 あれぐらいで頭オカシイ、完全に発狂って言うようじゃ
C++プログラマ(C++を使えるといえない)とは言えない
テンプレートを活用しようとすると 少なからずマクロの力必要だし たぷるとかマクロなしでひとつひとつ作ってたら死んじゃう
>>832 ほう、ではお前さんはboostを超える物を何か書いて発表したかね?
>>834 可変長引数テンプレートの代替くらいじゃん
workaround以外でマクロの出番なんて普通にC++使ってればそれほどない
少なくとも日常的に使うほどではまずない
boost使うのはともかく、書くのは日常じゃないしな。
ところで、おまえらはboostぐらいのレベルのライブラリを作れる?
近いうちに俺のコードがマージされそう。
つ boost::progress_display
boost::progress_timerはちょっとしたベンチマークに便利だな QueryPerformanceCounter()を使った簡単なクラスを組んであるけど これよりもっと手軽だ
Rubyバカにしてる子ってさ 変数に$ついてる言語触ってるって事だよね いちいちSHIFT+4キーおして $ 打ちまくってる感触はどう? ゴミ
通報済み
844 :
デフォルトの名無しさん :2011/11/22(火) 12:54:48.41
なにこれ
845 :
デフォルトの名無しさん :2011/11/22(火) 14:42:42.58
>>842 Perlの事ならおれに言え!シュボー!!
しかし、変数の前に常に $ をつけるのも、悪いことじゃないと思うんだ。 というのも、結局、どこかの流派の人たちはクラス名の前にかならず C をつけたり、 データメンバのまえに m_ をくっつけたりするからだ…。 クラス名は先頭が大文字ならそれでいいのに。
変数名に$をつける言語なんかBASICくらいしか使ったこと無い 文字列のプレフィックスだよな
Rubyはメンバ変数に@を付けるね
C++も頭かお尻に m_ とか _m を付けるハンガリアン記法が便利
>>847 BASIC は suffix だろ、しっかりしてくれ。
perlも$付けるよ
$安いよね
853 :
デフォルトの名無しさん :2012/07/18(水) 15:28:56.39
>std::vector<Point> Points; >Ponit *pPt = Points.insert(Points.end(), Point()); このとき、pPtが参照しているメンバーは何番目のメンバーか把握できるのでしょうか? orz
vectorだから、pPt - &Points[0]で足りるんじゃねーの
>>854 vectorの返すイテレータはポインタとは限らないぞ
そんなことは百も承知。だからbegin()を使っていない。
Points.size() - 1
>>855 で、質問をちゃんと読んでから、偉そうにコメントしてくれ。
>>857 馬鹿か?
Points.size() - 2
だろ
おまいらが喜ぶレス付けてやったんだよ。 ありがたく思え。
end() は要素じゃないんじゃない?
862 :
853 :2012/07/18(水) 16:18:17.49
つ [d] C言語的な解決策はあったわけですね。その手段でやるしかないですね。 逆にイテレータンを経由した書き方で、853を書き替えたらどうなるんでしょう。 でもイテレータンだと、何番目のメンバーとか取れないのか。。。 何だかSTLって悩みますね。
end() は要素じゃないんじゃないんじゃないんじゃない?
864 :
853 :2012/07/18(水) 16:20:39.48
>end() は要素じゃないんじゃない? >end() は要素じゃないんじゃないんじゃないんじゃない? どっちですか(><) 何年もこの書き方なんですが、今さら違ってると言われたらガクブルw
STL関係ないわ スレ違いもいいとこ
end()が要素だったらend()の前にinsertしたら最後の要素じゃなくなるよね
つ[distance()]
870 :
853 :2012/07/18(水) 17:37:10.50
>>868 ベクタンのイテレータンって、ポインタで良かったんでしたっけ?
だとすると、
>std::vector<Point> Points;
>Ponit *pPt = Points.insert(Points.end(), Point());
>int iIndex = distance(pPt - &Points[0]):
ですか?
871 :
853 :2012/07/18(水) 17:56:59.47
経験則でおk、とは思いませんが、 >std::vector<Point> Points; >Ponit *pPt = Points.insert(Points.end(), Point()); >int iIndex のとき、 >iIndex = Points.size() - 1; >iIndex = distance(Points.begin(), pPt); の両方とも、上手く動作するっぽいですorz
>>869 end()
文法:
iterator end();
end() 関数はベクタの末尾を指す イテレータ を返す。
ベクタの最終要素にアクセスするは、イテレータをデクリメントする必要があることに注意。
関連項:
begin()
873 :
デフォルトの名無しさん :2012/07/18(水) 18:08:55.57
つまりどういうことです?
size() == 3のとき。 ■←begin() ■ ■ □←end()
875 :
デフォルトの名無しさん :2012/07/18(水) 18:12:42.85
size() == 3のとき。 ■←begin() ■ ■←back() □←end()
>επιστημηです。
>
>--- "[cppll:9733] Re: std::vector の要素の連続性" ---
>
>>2000 年08月に vcpp mlで、「規格上は中身をどう実装しようが勝手なんで、
>>std::basic_stringを用いる手もアリかも」という話がありました。
>
>規格上は中身をどう実装しようが勝手なんで、
>std::basic_stringの要素が連続してる保証が…
># 実質上おっけーですけど^^;
>
>ま、欲しいバッファがconstでいいなら basic_string::data() 呼べば。
1要素insertするたびに全要素分の配列再allocateされて 全要素コピーされてたでござるの巻
>>859 しかし、じっさいに動作させると、
>Points.size() - 1
で上手くいくのですが?
>Ponit *pPt = Points.insert(Points.end(), Point()); これって、インサートしたものが末尾になっているような気がするのですが、 間違いですか?
>>879 じゃぁそれでいいじゃないか。このスレにもバカはいるさ。
>>880 自分で確かめられるだろ。
back から insert ですね わかります
vectorのメモリ管理って: struct Rec { std::vector<Rec> InArray; }; std::vector<Rec> OutArray; のとき、 OutArray.clear(); ってやっても、 InArrayがクリアしてなかったから、メモリリークになった、 なんてことは無いですよね?
ありますよ
885 :
883 :2012/07/20(金) 13:42:08.73
え”ー、そうなんですか? InArray.clear(); してから、 OutArray.clear(); しろ、 ということですか?
>>876 コイツ前から思ってたけどマジで日本語書かないよな
C++やりすぎるとこうなるらしい
お前ほどじゃない
コンパイルできないからリークもしないよな
こんな過疎スレにまで来てるのか
891 :
uy :2012/07/21(土) 03:09:27.18
>
>>2000 年08月に
まずこの08月ってのがいきなりうざい
>
>>2000 年08月に vcpp mlで、「規格上は中身をどう実装しようが勝手なんで、
>>規格上は中身をどう実装しようが勝手なんで、
「規格上」は? はぁ?????「規格では」とか言えばいいのに
しかも何で二回いってんの
しかもその後
>># 実質上おっけーですけど^^;
また「○○上」って単語がでてきた 最後の顔文字なんでつけたの? ねえなんで「^^;」←この顔文字をつけたの? この顔文字つける意味あった?ネェなんで顔文字つけたのー?
ほんのわずかな文章で 規格上 規格上 実質上 って3回も変な単語でてきたよコイツ
次、
>>std::basic_stringの要素が連続してる保証が…
はぁ???
最後まで喋れよ
>>ま、欲しいバッファがconstでいいなら basic_string::data() 呼べば。
、ま、ま、ま、ま、ま「、ま」じゃねーよ何もまとまってないし、 呼べば。 でまた文章とまってる
はぁ???
なにこれ、
最後まで発音できないの?
>>std::basic_stringの要素が連続してる保証が…
>>ま、欲しいバッファがconstでいいなら basic_string::data() 呼べば。
いい加減にしろ
謝れ
俺が言いたいのはそれだけ
892 :
uy :2012/07/21(土) 03:10:14.09
呼べばなんだよ 保証がなんだよ ふざけんな
まずお前が and でも or でもないものを and とか or とかいうのをやめてから言え。
何の話や?
そんなカッカすんなよ uyも大してかわんないからさ
896 :
uy :2012/07/22(日) 22:19:36.62
>>883 「わかりました。」「まかせてください。」
↓ 数時間後
「は?こんなもん作れって言ってない」
ゴミ
std::swap_ranges アルゴリズム
一時オブジェクト嫌いや( `д´) ケッ!
>>898 C++11はいいぞー
ムーブコンストラクタがどんなに便利か
そしてSTLもかなり速くなっている
900 :
デフォルトの名無しさん :2012/08/20(月) 09:07:00.31
C++11とSTLが速くなってるってどういう関係が?
ムーブコンストラクタが効いてるんじゃない?
>>899 898です。
現場がまだそれ(C++11)に対応して無いから仕方無いんだけどね。
愚痴ってしまった。
どう考えてもC++03の 一時オブジェクトを作る→それをコピー→一時オブジェクトを破棄 って無駄だろうが C++11では出来る場所では 一時オブジェクトを作る→即そのポインタもしくは参照を変数に代入 というわけで無駄がないし速くなる
>>903 > 一時オブジェクトを作る→即そのポインタもしくは参照を変数に代入
とても正しく理解できているようには読めんな。
906 :
906 :2012/10/23(火) 11:53:50.37
>std::vector<Point2D> Points; >Point2D *pP = Points.insert(Points.end(), Point2D()); 某系のコンパイラでは通るのですが、gccでコンパイルエラーです。 この書き方って間違ってますか?
907 :
906 :2012/10/23(火) 11:56:54.19
>-build-desktop-Qt_4_8_1__Qt-4_8_1__Release/../../TPolygon.h:72: エラー: cannot convert '__gnu_cxx::__normal_iterator<Point2D*, std::vector<Point2D, std::allocator<Point2D> > >' to 'Point2D*' in initialization
class Point2D { public: void print() const { std::cout << "Point2D" << std::endl; } }; int main() { std::vector<Point2D> Points; std::vector<Point2D>::iterator pP = Points.insert(Points.end(), Point2D()); pP->print(); Point2D* pP2 = &*pP; pP2->print(); }
909 :
906 :2012/10/23(火) 12:55:05.18
910 :
906 :2012/10/23(火) 18:16:35.57
度々すみません。 つまり、gccではベクタンで、 「ポインタ→イテレータン」はキャストOK、 「イテレータン→ポインタ」はキャストNG、 ということでしょうか? 「イテレータン→ポインタ」はどう書けるのでしょう?
>>910 pointer = &* iterator;
ケツにぶち込むなら pointer = &Points[Points.size() - 1];
913 :
906 :2012/10/24(水) 09:20:48.54
つ orz なるほど、イテレータンから一旦実体化してさらにアドレス取るんでつね。 盲点というか、それならコンパイルエラー起きようがないです。
イテレータから取ったポインタを++とかやりそうで危ういな
915 :
906 :2012/10/24(水) 10:36:10.51
それはベクタン限定なら無問題では? ポインタンを保持するとダメなだけで。 ってSTLの最大の欠点は、何が危ないか難しい事ですよね。
ポインタの vector にしてると また色々ミスが出てくる
>>916 ああ再配置か
いつ起きるか分からないから怖いな
まあだいたい起きる時の指針はあるけど
ooタン
919 :
デフォルトの名無しさん :2013/02/10(日) 15:40:08.47
質問です。 VC++2008でvectorを使っているのですが、デストラクタでのclear()呼び出し時に、vector::_Orphan_range と言う関数内でアクセス違反が発生しています。 関数内でvector内をいじる箇所を全部コメントアウトしても、同じ箇所でエラーが発生します。 どこかで何かを見落としている結果だとは思うのですが、全く思い当たる節がないため、 煮詰まってしまいました。 なにか、このエラーが(_Orphan_range()で)発生する理由があるのでしょうか。 どなたかご教授願えませんでしょうか。
>>920 問題の切り分けで再現ソースを作ろうとしているのですが、試みがうまくいっていない状態です。
先ほどから試行を続けて、スレッド内からスレッドを立ち上げ、クラスのメンバ変数となっているvectorで
begin()を実行してiteratorの値を得ると、エラーが発生することがわかりました。
(何故かiteratorを得ないでbegin()だけ実行してもエラーとならない)
コピーコンストラクタ, operator=
vectorに指定してる型のメンバにポインタがあるのに コピコンとoperator=をちゃんと定義してないからじゃねーの
そうです。それです。 無事解決しますた。
Boost.SmartPointer使っとけ
イテレータはなんでそれ自身で終端を判断できるようにしなかったんだろうね? オブジェクト内部で保持する要素を列挙するのにJavaの感覚でイテレータだけ 返す関数を作ったら、いざ使おうとしたときに「あれ?」ってなったわ。
自前のイテレータにhasnext実装すれば良いだけじゃね?
では、実例を。kwsk ↓
C++におけるイテレータの基礎はポインタだから、ポインタ互換が自然だった。 終端を判断できるオブジェクトはイテレータ範囲(iterator range)という概念として boostのrangeライブラリで実装されており、今後標準でもサポートしていく予定になっている。
Javaってほんとくそだな
stlportのunordered_mapは実用的ですか? mapを置き換えたいんですが、 他によいライブラリあるかな? VC6です。
stlporのおのじゃないけどunordered_mapは正式採用されたから実用に耐えるんじゃないの
STLportのunorderedコンテナは以前試した時はboostのより性能がよかった。 今はどうかとか他人の環境でどうかなどは知らん。
934 :
931 :2013/03/29(金) 18:20:52.87
使えました@vc6 最初はboostでやろうと思ったのですが、 1.34.1までしか対応してないらしいという情報を見て、 そのバージョンはまだuom対応してなくてstlrortにたどり着きました。 やはり普通のmapに比べてかなり速いですね ただinsertに使うイテレーターが関数の種類によって違うのは仕様なのかな? ちょいハマりました。 最新のバージョンは標準のiostreamは使えなくなってるらしいので注意が必要
>>934 VC2010でiostreamは普通に使えているが。
>>935 _STLP_DONT_REDEFINE_STDでつかうってことですか?
v5からラッパーモードはなくなってstlport内では
完全にstlport独自のiostreamの実装を使うようになった。
REDEFINEしない場合は、
stlport::xxxと(コンパイラ提供実装の)std::xxxとは、個別に使えるが、
stlport::xxxとstd::xxx間のやり取りは注意が必要的な認識なんだけど。
>FAQ
>Q2.3 Can I mix STL implementations in my project?
と
>ReleaseNote
>5.0:
>- Major modifications
> * No more wrapper mode: you can use STLport iostreams or no iostreams
> at all.
調べたけどこんなのでてきたしまだよくわかってない
http://sourceforge.net/projects/stlport/forums/forum/490891/topic/4089488 まぁライブラリとしては問題なく使えてるからいいか
937 :
デフォルトの名無しさん :2013/09/05(木) 00:16:36.10
テスト
938 :
デフォルトの名無しさん :2013/09/05(木) 00:25:49.15
質問です。 vector<int> vt; (以下vtに配列代入) vector::<int>::iterator i; i = list.begin(); と書いて実行したらAccessViolationが発生しました。 vector::<int>::iterator i = list.begin(); と書いたら問題はありませんでした。 この2つの書き方はどのように違うのでしょうか?
>>938 前者は代入。後者は初期化。
list の型がわからんからエラーの原因は知らんよ。
知りたかったらエラーの再現する最小コードを作ってみるといい。
940 :
938 :2013/09/05(木) 02:56:49.74
あ、間違えた。 vector<int> vt; (以下vtに配列代入) vector::<int>::iterator i; i = vt.begin(); です。 一応これが最小コードです。
941 :
938 :2013/09/05(木) 03:02:34.13
Iteratorの代入を行った場合、すでに確保されているiの参照先アドレスが vt.begin()のアドレスに書き換えられるだけかと思っていたんですが、 もしそうなら例外が発生する理由がわからないので・・・
iの型が違うとか? イテレータって大抵参照だよね
>>940 > (以下vtに配列代入)
そこ省略しちゃ最小コードとは言えないよ。 main も無いし。
codepad や ideone に貼り付けてテストできるようにすれば
環境依存の問題かどうか切り分けられる。
ちなみにコンパイラ何使ってるの?
945 :
938 :2013/09/07(土) 00:38:59.00
すみません。今代入を含めてコードを簡略化してます。 あとで指定のURLに書き込みます。 推測で書いていたら違うところがありました。
946 :
938 :2013/09/07(土) 04:20:39.04
コードを下記に記載しました。 (コードパッドURL)/FdcWwKqq (※URLを貼り付けられないと表示されるので、上記の記載で勘弁してください) 実行自体はできるのですが、動的解析をするとAccessViolationがIteratorに 代入するところで発生します。 環境はLinuxのg++でコンパイル、実行してます。 先のコードはかなり勘違いしてました。申し訳ありません。
>>946 はじめいってたこととずいぶん違うじゃないか?
普通の状態で問題なくコンパイル実行できるので 動的解析ツール側の問題だと思う
949 :
938 :2013/09/08(日) 02:25:50.84
>>947 申し訳ありません。
別のコードと勘違いしていました。
>>948 コンパイル実行が一見できていても
実はメモリ破壊していたということがあるので
その類かと思ってます。
もちろんツールの不具合の可能性もありますが。
>>946 ぱっと見だだけだけどconstがらみじゃないの?
あと、気になっただけなんだけど、std::stringに入れる文字列をunsigned char*で定義して
あとからわざわざchar*にキャストするのはなぜ?
951 :
938 :2013/09/08(日) 23:13:57.56
unsigned char* で定義したのは関数の戻り値がこの型なので。 簡略化するためにunsigned char*の配列で定義しました。 String型にpush_back()するためにchar*に変換する必要がありました。 やっぱりconstからみですかね・・・
constが絡むならstringのコンストラクタ付近で出るだろうし 完全に別のインスタンスになってるこんなところでエラー出るとは思えない
953 :
938 :2013/09/12(木) 23:36:07.21
ツールの不具合っぽい方向ですすめることになりました。 いろいろありがとうございました。
954 :
デフォルトの名無しさん :2013/09/14(土) 10:59:23.00
流れ読まずに書くけど、他のオブジェクトへの参照を持つクラスのvectorのpush_bachではまった。 単純化して書くと、 struct person { person* p; person(person* other=0) : p(other) { } 他のメンバ; }; int main() { std::vector<person> Vec; Vec.push_back(person(0)); Vec.push_back(person(&pV[0])); Vec.push_back(person(&pV[1])); ・・・ push_backで再アロケートが起こると壊れる。
>>954 単純化(?)よりも、動いて実際に壊れるコードをだしてくれ。
そうじゃなきゃ、なにが問題かなんてわからんだろ。
956 :
デフォルトの名無しさん :2013/09/14(土) 11:16:44.55
>>955 Vec[n].p == &Vec[n-1]
が成り立ってると思ったら、Vec[n].pが指してる場所は消滅している。
reserveしてからpush_backするか、resizeしてから各Vec[i] へ代入しなきゃダメ。
personはデフォルトのコピコンと代入演算子でOKなクラス。
デストラクタで delete p もしてない。
コンテナの要素としての要件は満たしているんだけどね。
そりゃおめえvectorの中身のアドレスなんだから メモリ上の位置変わっても文句言えねえだろ
なんかおかしくない? なんでnとn-1が同じところを指すんだか pVもどこからでて来たかわかんねーし…
コンストラクタに渡されるのは再配置前のアドレスなんだから当たり前だよなぁ
>>958 書き間違い
× Vec.push_back(person(&pV[0]));
× Vec.push_back(person(&pV[1]));
○ Vec.push_back(person(&Vec[0]));
○ Vec.push_back(person(&Vec[1]));
本当に必要だったもの: std::vector<person*>
コレクション要素を指すポインタを保持したり他に渡したりするのは厳禁、 イテレータも有効範囲に注意してし使わなければならない、ってのはSTLを 使い始めてごく初期に学ぶことと思っていたが。
>>962 そうだね。外部イテレータが無効になるのは誰もが意識してるだろうけどね。
今日日、何が悲しくてc++なんて使ってんだろう
>>961 それ、boost::ptr_vectorにしといた方がいい
そんな便利な物があったのか 全然知らんかった
今だったら普通にshared_ptrに包んでvectorに突っ込んだ方が楽だけどな
ptr_vectorって変な制限が多いでしょ
970 :
デフォルトの名無しさん :2013/09/25(水) 15:41:46.87
std::stringのend()って、 必ず末尾のNULL部分なのでしょうか? >char cLast = *(SBuf.end()); >if (cLast == 0) { > cLast = *(SBuf.end() -1); >} みたいな処理を書いていますが、コンパイラによっては、 1行目で吹っ飛びます(><)
971 :
デフォルトの名無しさん :2013/09/25(水) 15:49:09.49
それ以前に色々間違ってる
973 :
デフォルトの名無しさん :2013/09/25(水) 15:59:01.05
意外と長寿スレだったぬ
974 :
デフォルトの名無しさん :2013/09/25(水) 17:04:28.72
間違ってるなら、正しい記述を教えて下さいorz
end()は例えばCで言うと int a[10]; の a[10] みたいなもんで、アドレスとしては有効だけど 領域が確保されてないので中身にアクセスすると未定義 単にイテレータを比較するためのだけのもの ちなみにイテレータの比較に < を使わず != を使うのは、random_access_iteratorだけじゃないため
>領域が確保されてないので中身にアクセスすると未定義 有難うございました。 >random_access_iteratorだけじゃないため 今一つ意味が。。。
>>976 例えばstd::listはbidirectional_iteratorなので要素順としては連続していても
アドレスがあべこべの順になっているなんて事はよくある
だから < で比較しない
というか実際に自分で試してみて「あれっ?」と思う体験が大事
>>970 std::string で末尾が NULL なのは c_str() でアクセスした場合。
末尾の文字が欲しい場合は
const char cLast = SBuf.empty() ? 0 : *SBuf.rbegin();
とかする。
空文字列の時に rbegin() を逆参照してはいけないので注意。
君の *(SBuf.end() -1) も空文字列の時にダメ。
*(SBuf.end()) は常にダメ。
'\0' と NULL を混同するんじゃねぇ
>*(SBuf.end()) は常にダメ。 なるほど、STLの.end()って、ここでしか使ったこと無かったんですが、 既にデータの外だよ、 という意味でしたか。
イテレータの実装が単なるポインタのvectorでend()の値が何になるか・・・を考えてみればok
>イテレータの実装が単なるポインタのvectorでend()の値が何になるか・・・を考えてみれば って、最後の文字のポインタになってて、最後の文字取得出来た方が便利じゃん?
std::stringとc_str()は違うのよん int main() { std::string str("Test"); std::string::const_iterator pos = str.begin(); for (int i = 0; pos != str.end(); i++, ++pos) std::cout << "str[" << i << "] = " << *pos << std::endl; for (int i = 0; i < (int)strlen(str.c_str()) + 1; i++) { std::cout << std::dec << std::noshowbase << "str.cstr[" << i << "] = '\\"; if (str.c_str()[i] == '\0') std::cout << "0x00' ←Terminate character" << std::endl; else std::cout << std::hex << std::showbase << std::setw(4) << std::setfill('0') << (int)str.c_str()[i] << "'" << std::endl; } }
わざわざendやrbeginを持ち出さなくてもbackがあるわけだが
>>984 そんな事は分かっている
それにrbegin()もあるし
c_str()の場合はどうするんだ?
>>970 を見る限り最後の文字を取得したいだけっぽいからback()で十分なんじゃないの?
>>978 とかイテレータを経由する意味がまったくわからないし
そんなもん人の勝手だろうが 文句あるんなら自分で書け
中途半端な親切心でレスするのも間違い
親切心ではなくてこの場合は単なる言い掛かり ム板なら黙って改良版を書いて示して「こっちの方がすっきりしてるだろ」と言う方がいい
>>970 char cLast = SBuf.back();
こっちのほうがすっきりしてるだろ
空文字列のときどうしたいのかはわからないから好きにしろ
991 :
970 :2013/09/27(金) 09:09:41.20
>char cLast = SBuf.back(); あ、これで最後の文字が取れるんですか。 これが知りたかったことかもwww >空文字列のとき は、size()で判定済みなので、無問題です。
back()はC++11ね C++03にはない
>back()はC++11ね orz
だから、*(SBuf.rbegin())でいいじゃないの。
こうしないと空文字列の時未定義の動作 if (SBuf.length()) std::cout << *SBuf.rbegin() << std::endl;
あ、 >SBuf.rbegin() てのが最後の文字を指して(rってのは、reverseだとオモ)、 >SBuf.begin() てのが最初の文字を指すんだ。 orz
C++03って細かい所で結構未完成なんだな C++11で結構詰められている そりゃ8年も掛けたんだもんな
もうPL/Iどころの騒ぎじゃなくなって来たな 世界最大規模の言語かよ もっともライブラリを入れたらJavaやC#もすごい規模なんだけど
1000 :
◆Cj98aJOpxg :2013/09/28(土) 06:46:47.54
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。