- 1 名前:デフォルトの名無しさん [2008/02/27(水) 02:03:30 ]
- C++標準ライブラリの一つ、STLについて。
前スレ 【C++】STL(Standard Template Library)相談室 8 pc11.2ch.net/test/read.cgi/tech/1198435319/ 過去ログ・リンク・書籍紹介は >>2 以降
- 151 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:11:41 ]
- std:stringのバッファの連続性が保証されることは、&str[0]とstr.c_str()のアドレス同一性を保証しますか?
- 152 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:15:31 ]
- 保証しない。
c.str を呼んだ場合、メモリの最確保が行われる可能性がある。
- 153 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:17:32 ]
- なるほど。str.data()はどうでしょうか。
- 154 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:19:05 ]
- 残念ながら data も同じ。
- 155 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:22:21 ]
- しかしなんだな。
今の規格ではバッファの連続性を保証していなくて、 次の規格ではバッファの連続性を保証する予定ではあるのだが、 連続性を保証したら data で参照、ポインタ、イテレータが失効する可能性は もう無くなるとしてもいいような気がするんだけど、 最新のドラフトではそうなってないんだよな。 ミスなのか、それとも何か深い理由でもあるのか・・・。
- 156 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:25:17 ]
- >>155
正直プライオリティ低いんだろ どうでもいいわと思ってる委員が多いと予想
- 157 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:26:44 ]
- しかし、そろそろそういう細かいところも詰めていかないと、
0x の x は16進数ってのもあながち冗談では済まなく・・・。
- 158 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:28:14 ]
- いざとなったら得意のundefined behaviorでいいだろ。
- 159 名前:デフォルトの名無しさん mailto:sage [2008/03/06(木) 21:51:10 ]
- やたらスレが伸びてると思ったら・・・
もうここの連中には仕事任せられんな 今後は>>170にすべてを託すこととする なお異論は受け付けない
- 160 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 04:52:01 ]
- それは無意味にkskしろってことかい
- 161 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 09:34:55 ]
- string::swap について教えて下さい。
>void func(string &sArg) > string sBuf = "AAAAAA"; > sBuf.swap(sArg); のときって、sBufの内容がsArgに移し変えられるっていうのがswapの機能だと思います。 この場合、実装に依存するんだと思いますが、 メモリのエリアがガバっとコピーされるのではなくてクラスの参照を交換してくれるんでしょうか? 性能的に優れてるものだったら、使いまくりたいですし。 一度も使ったこと無いので、swap後にちゃんとメモリ保持しててくれるんだろうか、 落とし穴は無いだろーななんてガクブルしてます。
- 162 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 09:55:42 ]
- >>161
stringだったら、内部で保持しているであろう 文字列へのポインタや長さなどといった変数だけが交換されるとみな仮定している。 一般的に、swapは例外を投げないとされており、 しかも、std::stringのswapはO(1)と規格で定められている。 だから、文字列の中身まで交換する実装はありえない。
- 163 名前:161 mailto:sage [2008/03/07(金) 10:29:50 ]
- サンクス。
>一般的に、swapは例外を投げないとされており、 へぇー、勉強になりました。 >しかも、std::stringのswapはO(1)と規格で定められている。 勉強になりましたが、O(1)って何だ?_? >だから、文字列の中身まで交換する実装はありえない。 あ、そうなんですか? 例外を発生できないとなると、参照を交換する以外に実装無いと思うんですが。 だって、交換じゃなくてコピーならば、メモリを確保しないといけないし、そうなるとエラーが発生する可能性があるような。 って素人なのに生意気逝ってすみません。
- 164 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 10:37:30 ]
- O(1)というのは、例え文字列が長くてもswapが一定時間で終わらなければならないってこと。
文字列をコピーするなら、文字列が長くなればそれだけコピーに時間が掛かるから、この制限を満たせない。 詳しくは「計算量」でググれ。 >例外を発生できないとなると、参照を交換する以外に実装無いと思うんですが。 まさに>>162はそう言ってるんだと思うよ。 中身をコピーして交換するんじゃなくて参照(具体的にはポインタ)を交換する。
- 165 名前:161 mailto:sage [2008/03/07(金) 10:40:31 ]
- ラジャ!
>文字列の中身まで交換する実装はありえない。 つまり、中身をコピーする実装はありえない、って文章ですね。 で、そう言い切れる理由はO(1)で時間制限してて、”ま、参照を交換する実装にしる!”、っていわば指令が出てるわけですね。
- 166 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 10:58:42 ]
- >>165
deep copyをするとno throwの保障ができなくなる。
- 167 名前:161 mailto:sage [2008/03/07(金) 11:00:02 ]
- すみません、教えてクンですみませんが、最後に記述を教えて下さいorz
swapを使いまくりたくなりました。 vector<char>とstringの間で、swapする記述はありますでしょか? vectorメモリは連続しているので、vector同士だとswapできるんじゃないかと思ったのですが。 直にメモリアクセス?イテレータンを無視し過ぎるのも良くないとは思わないでも無いですが。
- 168 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 11:07:45 ]
- >vector<char>とstringの間で、swapする記述はありますでしょか?
ない。実装上も、例えばstringがnull終端の分だけ余計に内部バッファを持っているなら無理。 >vectorメモリは連続しているので、vector同士だとswapできるんじゃないかと思ったのですが。 vector同士ならできる。
- 169 名前:161 mailto:sage [2008/03/07(金) 11:09:58 ]
- >ない。実装上も、例えばstringがnull終端の分だけ余計に内部バッファを持っているなら無理。
なるほど。納得。下手にやるとはまりますね。 >vector同士ならできる。 vectorの異なる構造体同士でもできますか? 記述例超キボンw
- 170 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 11:19:32 ]
- テンプレートパラメータが違うとダメだろう
- 171 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 11:28:20 ]
- 記述例もなにも、vとv1が同じ型のvectorなら、
v.swap(v1); で交換できる。vectorに限らずあらゆるコンテナで。
- 172 名前:161 mailto:sage [2008/03/07(金) 11:36:47 ]
- 全部分かりました。有難うございましたorz
つまり、コンテナが違うとswapはキャストやらなんやらやヴぁい記述になるわけですね(はまるからやらないけど)
- 173 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 13:11:25 ]
- 質問です。
クラスメソッドの引数で、 >method(string s1) { method(s1.c_str()) } >method(const char *s1); みたいな感じで、オーバーロードで「string」も「char *」も両方受け入れるようにしてるんですが、 どちらか片方だけ定義、ということにできますでしょうか?
- 174 名前:173 mailto:sage [2008/03/07(金) 13:15:17 ]
- 2つ要るとしたら、stringベースとchar*ベースと効率が良いのはどちらでしょう?
まぁ、大差無いですか?
- 175 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 13:20:59 ]
- >>173
stringだけ書いとけばconst char*からstringを暗黙に構築してくれると思うが、効率は良くないかも
- 176 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 13:37:12 ]
- >>173
片方がconst char * なんだから、string const & の方がいいんでないかい? で、どっちみちstringを受ける方もconst char * 版を呼び出すなら要らないわけで。
- 177 名前:173 mailto:sage [2008/03/07(金) 13:37:33 ]
- 何だ、そうでしたか。無駄に2つ作ってしまったorz
- 178 名前:173 mailto:sage [2008/03/07(金) 13:42:12 ]
- 頭が混乱してましたが、
>stringだけ書いとけば の場合は、引数が入力である場合は、おk、 >片方がconst char * なんだから、string const & の方がいいんでないかい? これ(つまり、& )を選択した場合は、2つ書かないといけないんですよね? コンパイラで試せば良いのですが、皆さん普通はどうされてるのか知りたくて。
- 179 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 13:44:52 ]
- >>178
わけがわからん。何がしたいのか書きなおしてくれ。
- 180 名前:173 mailto:sage [2008/03/07(金) 13:48:53 ]
- ごめんなさい、テストプログラム書いたら違っていました。
つまり、 >stringだけ書いとけば でおk。 >string const & の方がいいんでないかい? でおk。 但し、char *を渡すと、W8030 Temporary used for parameter のウォーニングが出ると。
- 181 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 13:52:35 ]
- 話を読む限りstringやconst char*である必要性を感じないし、
俺だったら初めと終わりのイテレータを引数に取るようにする。 stringでもconst char*でもないやつもかかってこい。
- 182 名前:173 mailto:sage [2008/03/07(金) 13:53:05 ]
- あ、「「string &」だとウォーニングだったのが、「string const &」だとウォーニング消えました。
つまりやりたかった、 >string と char *の一本化、 および、 >参照渡しでメモリ節約&コンパイルウォーニング無し の全て解決しました。orz
- 183 名前:173 mailto:sage [2008/03/07(金) 13:54:45 ]
- >俺だったら初めと終わりのイテレータを引数に取るようにする。
はつみみです。 これ知っとくと大分楽できそうですね。何が良いのか調べてみます。 (参考サイトでも何でも教えて頂ければ参照します。レスで教えてというのも嫌われそうなので)
- 184 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 13:58:47 ]
- string const &が要求されてるところにconst char *を渡そうとしたら、stringの一時オブジェクトが作られて、
文字列の内容がコピーされるから、メモリの節約にはなってない
- 185 名前:173 mailto:sage [2008/03/07(金) 14:20:17 ]
- >>184
あっ、そーですか。 じゃぁ、今まで作った基礎クラスはそのままに2つのままにしておこうかなぁ。。。 悩む。
- 186 名前:173 mailto:sage [2008/03/07(金) 14:58:05 ]
- 今、上記内容に沿って、”string const &型”に全面書き換え中ですが、
以外に頭が固いのが、stream系ですね。 っていうか、ifstreamとか引数にstring受け入れないっぽい。
- 187 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 15:26:37 ]
- >>186
コードを書く前に、もう少しきちんと勉強したほうがいいと思います。
- 188 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 16:40:31 ]
- class StringArg
{ const char* p_; public: StringArg(const string& str) : p_(str.c_str()) {} StringArg(const char* str) : p_(str) {} const char* get_arg() const { return p_; } }; method(const StringArg& arg);
- 189 名前:172 mailto:sage [2008/03/07(金) 16:49:34 ]
- >>188
はじめそれに近い形で書いてたんですが(違いはstring側はconstにしてなかったとこだけ)、 メソッド宣言2行になると、以外にクラス部品作るのがしんどくて。 効率悪くても1つにしたいな、と思いました。 で結局、 >StringArg(const string& str) の方だけ活かして、 巨大なバッファで、かつ、char *の可能性がある場合のみは、188 の通り、 2つ宣言しようかと思っています。
- 190 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 16:50:09 ]
- ↑
172じゃなくて、173でした。
- 191 名前:デフォルトの名無しさん mailto:sage [2008/03/07(金) 16:58:43 ]
- >>189
多分お前は>>188を誤読してる const char *をとるメソッドもconst string &をとるメソッドも用意せずに、 const StringArg &をとるメソッドを用意しろってことだろ
- 192 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 09:00:47 ]
- void Method(const char*); のみ用意して、
std::stringを渡したい場合は↓じゃあかんのか std::string s; Method(s.c_str());
- 193 名前:デフォルトの名無しさん [2008/03/08(土) 20:47:51 ]
- #include <set>
using namespace std; int main() { set<int> s; s.insert(1); s.insert(4); (*s.begin()) = 5; return 0; } 上のプログラムは違法ですよね? ウチのコンパイラは文句を言わないんだけどおかしいですよね?
- 194 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 20:53:45 ]
- >>193
とりあえずg++だとエラーになった
- 195 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 20:59:06 ]
- ふぁっきんBCC
- 196 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 21:03:38 ]
- >>193
C++2003 に準拠しているならそれでも規格の範囲内。 変更できないことが明記されるのは次の C++0x から。 www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103 コンパイル通るからといっても、まずいことがわかってるなら やらないでおいたほうがいいね。
- 197 名前:デフォルトの名無しさん mailto:sage [2008/03/08(土) 21:04:28 ]
- >>193
Effective STL 第22項をどうぞ。
- 198 名前:デフォルトの名無しさん [2008/03/08(土) 21:12:44 ]
- >>196
サンクス。STLってたくさん欠陥があるんですね。 >>197 サンクス。今度立ち読みします。
- 199 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 08:45:25 ]
- stringにバイナリ書き込みで、
resizeした後、・・・1 c_str()でポインタ取って、・・・2 memcpy・・・3 してます。 2ってSTL的には読み込み専用ポインタであり間違ったコードなんですが、 動作してるのでほっとこうか、正しく書こうか迷ってます。 どうしたら良いでしょう?
- 200 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 08:47:18 ]
- >>199
間違ったコードを正しく書くのに、何を迷うの?
- 201 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 08:50:50 ]
- >>199
必要な知識は全部持ってるみたいだが、何を訊きたいんだ? 未定義動作に依存するという欠点よりもそのコードが持つ利点が大きいと考えるなら それを使い続ければいいし、そうでないなら書き換えればいい
- 202 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 08:50:55 ]
- いろいろ。
じゃ、直しておきまつ。
- 203 名前:デフォルトの名無しさん mailto:sage [2008/03/10(月) 20:18:13 ]
- コンストラクタやassignとかappendがあるもんな。
イテレータにstd::copyでもいけるし。
- 204 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 09:05:07 ]
- >イテレータにstd::copy
イテレータンって参照するだけじゃないんだ。 イテレータンがメソッド持ってるって考え方がイマイチわかんないんだおね。
- 205 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 15:29:40 ]
- いや、イテレータを引数に取れる関数だろ
- 206 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 19:51:25 ]
- イテレータは何かを反復するもの。「何か」は参照かもしれないし、操作かもしれない。
- 207 名前:デフォルトの名無しさん [2008/03/11(火) 20:59:59 ]
- ifstreamで半角空白を含むファイル名や、日本語を含むパスで
ifstream ifile(フルパス名);で失敗してしまうのですが、これは仕様なのでしょうか? 仕様なのでしたら回避策はあるのでしょうか? Visual Studio 2005SP1を使用しています。 よろしくおねがいします。
- 208 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 21:05:45 ]
- 問題が再現する最小限のコードを貼れ。まずはそれからだ。
- 209 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 21:05:59 ]
- ロケールの設定とか?
- 210 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 21:29:37 ]
- コンパイルはVisualStudio2005 Command Promptで行いました。
#include <iostream> #include <fstream> #include <windows.h> using namespace std; int main(int argc, char **argv) { ifstream ifile("新規テキスト ドキュメント.txt"); if(ifile) { MessageBox(NULL, "success", "info", MB_OK); ifile.close(); } else { MessageBox(NULL, "failed", "info", MB_OK); } return 0; } 結果はfailedとでます。
- 211 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 21:31:17 ]
- 間違えました。
フルパス名をコピペして、\を一つ減らしてエクスプローラーに貼り付けると正常に開けます。 ifstream ifile("d:\\新規テキスト ドキュメント.txt");
- 212 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 21:32:25 ]
- まさか、そのファイルがカレントディレクトリに置いてないとか言わないよな?
つーか、このスレより環境依存OKのスレかWindows関連のスレの方がいい希ガス。
- 213 名前:デフォルトの名無しさん mailto:sage [2008/03/11(火) 21:42:30 ]
- ありがとうございます。
環境依存スレに行ってみます。
- 214 名前:デフォルトの名無しさん [2008/03/12(水) 03:34:34 ]
- vectorに要素をpush_backするとき、全ての要素がこっそりと引越し、
要素を指していたポインタが無効になり、ひどい目にあうことが あるということを知りました。 そこで質問なのですが、引越し時の要素のコピーは コピーコンストラクタを使って行われるのでしょうか? それとも単純にmemcpyなどで行われるのでしょうか?
- 215 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 04:23:23 ]
- >>214
コピーコンストラクタじゃなきゃヤバイでしょ。 あくまで例だけど、int型のメンバxと、そのアドレスを持つint*型のメンバpxがあって、 pxの値をmemcpyなんかした日にはえらいこっちゃ。
- 216 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 07:50:53 ]
- >>214
もすこし具体的にどうぞ。 >>215 あんたも何を言いたいんだか。
- 217 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 07:51:34 ]
- コピーコンストラクタでpxをdeep copyしてなければ同じようにえらいこっちゃ。だけどね。
- 218 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 07:53:22 ]
- >>217
それは別問題
- 219 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 07:56:14 ]
- >>214
再割り当て時にはコピーコンストラクタが使われるよ。
- 220 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 07:57:26 ]
- >>216
俺は第三者だけど、>>214が何を訊きたいかは分かるし、>>215の回答も理解できるよ。 >>215は当を得た回答だと思う。
- 221 名前:217 mailto:sage [2008/03/12(水) 08:01:58 ]
- deep copy するわけじゃないのか。215が言いたいのは。
コピーコンストラクタでpx=&xが必要ってことだな。多分。
- 222 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 08:06:43 ]
- STLはコピーを前提に作られている。そういうもの。
- 223 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 08:07:42 ]
- >>214
要素は引っ越しません。
- 224 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 08:46:07 ]
- >>221
コピーコンストラクタという言葉を使っているところからして、 ユーザー定義型がvectorにどう扱われるかを訊きたがってるんだろうな、と判断した上で、 「コピーコンストラクタを用いなければ"正しく"コピーできない型があり得るのに、 vectorが内部で勝手にmemcpyによるコピーで満足しちゃうなんてことは無いよ」 って回答した次第。
- 225 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 08:49:23 ]
- >>223
嘘をつくな
- 226 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 08:50:39 ]
- >>223
規格に"引っ越し"という言葉は書いてないという揚げ足をとってるのか? それとも単にC++を知らないだけ?
- 227 名前:217 mailto:sage [2008/03/12(水) 09:01:52 ]
- I got it.
関係ないけどクラスをmemcpy、memcpyするソースをよく見かける。怖くて仕方ない。
- 228 名前:217 mailto:sage [2008/03/12(水) 09:02:25 ]
- memset、memcpyだった。
- 229 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 09:03:13 ]
- 怖いじゃなくて、memsetだとプログラム落ちるだろ、jk
- 230 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 09:05:39 ]
- そういうのはCのノリが抜け切れてない年寄りが多いの?
- 231 名前:217 mailto:sage [2008/03/12(水) 09:15:12 ]
- >>229
落ちるとは限らないよ。仮想関数がないクラスではうまくいく。(memsetでセットする値が適切なら) 仮想関数があるクラスでmemset(this,0,sizeof(this))とかやると 仮想関数ポインタが0になるので、 ポリモーフィズム使用時にNULLポインタアクセスで落ちた。 だから抽象クラスにしたいときには、memsetしてないか全部チェックせなあかんかった。 >>230 そうだね。特に組込系が多いね。クラスを構造体の延長として使ってる。
- 232 名前:217 mailto:sage [2008/03/12(水) 09:22:43 ]
- tp://sunlight.cocolog-nifty.com/sunlight/2006/11/class_56c5.html
こういう変なことする人もいる。class S が 仮想関数を持つクラスをメンバ変数に持ってたら ダメじゃんって突っ込みたい。 スレ違いでゴメン!
- 233 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 09:28:30 ]
- 突っ込みたいなら突っ込んであげればいいのに
- 234 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 10:05:25 ]
- >>232
君がインストラクタになってあげなさい
- 235 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 12:47:55 ]
- 引っ越しって言えば、moveだろ。
copyを引っ越しと言うのは無理があり過ぎる。
- 236 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 12:49:21 ]
- >>235
引越しは後片付けしてから出て行くよ。
- 237 名前:217 mailto:sage [2008/03/12(水) 15:43:34 ]
- 自分は暗黙のインストラクタでいいのでw
- 238 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 21:05:27 ]
- >>235
「copyを引っ越しと言」ってるようには見えないよ。「引越し時の要素のコピー」って書いてある。 コンピュータデータのmoveは、実際には「copyする」ことと「元を削除する」ことで成り立っているわけで、 つまり「move(ここではvectorの要素の再配置のこと)の手段としてのcopy」の表現だろう。
- 239 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 21:28:37 ]
- コピコンでは普通は deep copy する。
そういうもの。
- 240 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 22:56:24 ]
- 参照カウント付きハンドルの場合はそうじゃないけど。
(boost::shared_ptr etc)
- 241 名前:デフォルトの名無しさん mailto:sage [2008/03/12(水) 23:00:16 ]
- それは特殊例
- 242 名前:デフォルトの名無しさん [2008/03/14(金) 00:11:29 ]
- インストラクタwww
- 243 名前:214 [2008/03/14(金) 01:02:08 ]
- レス遅れてすみません。解答してくださったみなさん、
ありがとうございます。 でも、*ほとんどの* ケースでは、単純なmemcpyで済みそうなのに、 いつでもコピーコンストラクタが使われるという仕様に疑問を感じます。 コピーコンストラクタが使われるとなると、コピー元のオブジェクトに 対してデストラクタを呼び出す必要があります。これは、*ほとんどの* ケースでは全く馬鹿馬鹿しい無駄です。 それならreserve使え、とおっしゃるかもしれませんが、どれだけの 領域をreserveしておけばいいのか、前もって計算できないことも よくあります。 引越し時のコピーはmemcpyで行われるべきではないでしょうか? >>215さんが出した例のような場合、ユーザーはreserveを使います。 どうでしょう? だめ?
- 244 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 01:08:07 ]
- allocatorを指定するとか。
- 245 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 01:26:34 ]
- >>243
そう、毎度コピーするのは無駄と誰もが思ったから、 今度の規格改定でムーブセマンティクスというものが導入されようとしている。
- 246 名前:オガちゃん萌え ◆tyvkWCNtzY mailto:sage [2008/03/14(金) 01:27:09 ]
- インフラはmemsetやらをやたら使うよ
アーキテクチャ依存すんだからOOPは役に立たん ドメインでアーキテクチャ依存せんようにするにはやむえない …が、インフラのC型記述は拡張子.cにして欲しい イヴァーヤコブソンはそんなユースケース駆動モデルを奨めている STLですらQACでNGになられたんじゃ参るストーン
- 247 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 01:47:52 ]
- >>245
彼が不満に思っている状況の大半では, move semantics は何の改善ももたらさないのでは?
- 248 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 01:53:02 ]
- そうか?移動なら、コピーに比べ格段に低コストだし、
前のオブジェクトのデストラクタは実質やることなくなる。 こういう問題だと思っていた。214が納得するかどうかは別としてだけど。
- 249 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 02:09:19 ]
- >>248
memcpy によってコピーできるオブジェクトというのは, (C++0x において条件が緩和される) POD 型のオブジェクトに およそ相当すると思いますけれど,これらのオブジェクトに対しては コピーの操作と (move semantics でいうところの) move の操作は 同じ操作になると考えられるので「move semantics によって改善される」というのは まずいのではないかな,と. デストラクタに関しても, move を使っても copy を使っても 「実質やることがない」のはなんら変わりはないと思います.
- 250 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 10:11:23 ]
- >>249
ああ、たしかにPODだとそうだね。 言葉足らずですまん。俺は非POD型を入れることことを考えていた。 というのも243でデストラクタを呼び出さなければならないと言っているから、 214=243は非POD型を念頭に置いているのだと思ったため。
- 251 名前:デフォルトの名無しさん mailto:sage [2008/03/14(金) 12:04:02 ]
- >>243
手元のVC8ではvector<char>とかvector<int>ならmemmoveを使ってくれたよ。 アラインメントを考慮してrep movsdで転送。 struct Foo{int a; int b;}; vector<Foo>だと単純にループ1まわりにつき 8byte転送するようなコードになってた。 PODを判定できれば両方memmoveに出来るんじゃないかな。
|

|