【C++】STL(Standard ..
[2ch|▼Menu]
232:デフォルトの名無しさん
08/10/28 23:30:49
タイがあっても3つ以上はことはないとおもうんで、大丈夫そうです。

しかし動かないです・・・

233:デフォルトの名無しさん
08/10/28 23:34:12
>>229
>string maxkey='\0';

が良くない。これはstring maxkey=NULL; と同じ意味になる。
つまりアドレス0をアクセスする文字列で初期化しようとする。

234:デフォルトの名無しさん
08/10/28 23:35:44
基本からやった方がいいんじゃ・・・

235:デフォルトの名無しさん
08/10/28 23:37:58
>>233
if文内で代入するので問題ないかと思ったんですが・・・

>つまりアドレス0をアクセスする文字列で初期化しようとする。
??

236:デフォルトの名無しさん
08/10/28 23:38:35
微妙に誤解を招きそうなので訂正

×つまりアドレス0をアクセスする文字列で初期化しようとする。
○つまりアドレス0から始まるC文字列で初期化しようとする。

処理系によっては文字列が大きすぎて止まり、他の処理系では
アドレス0をアクセスするのでセグメントエラーで止まったりする。

237:デフォルトの名無しさん
08/10/28 23:39:17
正しくはstring maxkey=""; あるいは単にstring maxkey でいい。

238:デフォルトの名無しさん
08/10/28 23:40:39
>>235
charだけを引数に取るコンストラクタがないため、
暗黙の変換でconst char*を引数に取るコンストラクタが呼ばれてしまう。

239:デフォルトの名無しさん
08/10/28 23:40:40
わかりました。親切にありがとうございました

240:デフォルトの名無しさん
08/10/28 23:51:42
つーか、'\0'はintじゃね?

241:デフォルトの名無しさん
08/10/28 23:55:17
あとまだ質問が・・・

map<string,int> test;

while(){

if(条件){ }


}

として、条件が成立したときだけ、testを初期化(すべてのキーに対して値を0にしたい)したいのですが、どうすればいいですか?

242:デフォルトの名無しさん
08/10/28 23:55:37
>>240
だから、std::string::string(0) が呼ばれてしまう。
この意味をよく考えてみろ。

243:デフォルトの名無しさん
08/10/28 23:59:24
>>241
イテレータを回して全てのsecondに0を代入するしかないだろ

244:デフォルトの名無しさん
08/10/29 00:00:28
if(){

map<string,int> test;


}

ではだめですか?

245:デフォルトの名無しさん
08/10/29 00:04:15
>>244
それはまずい。if文の外側のtestが隠蔽されてしまう。

246:デフォルトの名無しさん
08/10/29 00:08:10
ネタとマジレスの見分けがつかない

247:デフォルトの名無しさん
08/10/29 00:08:27


map<string,int> test;

while(){

if(){

map<string,int> test;


}
}

でもですか?

248:デフォルトの名無しさん
08/10/29 00:10:01
>>247
同じ事だ。
>>246
うむ・・・釣られてるのやもしれぬ

249:デフォルトの名無しさん
08/10/29 00:15:38
決して釣りとかじゃありません。知識不足ですいません。

250:デフォルトの名無しさん
08/10/29 00:19:30
釣りじゃないなら

・差し当たってSTLよりも先にstringの予備知識を付ける
・スコープの意味を理解する

これは最低限やっておく事をお勧めする

251:デフォルトの名無しさん
08/10/29 00:20:28
わかりました!ありがとうございました

252:デフォルトの名無しさん
08/10/29 00:29:30
while(itr != itrEnd){

itr->second = 0;
itr++;
}
初期化はこんな感じですかね?
firstのstringの初期化もいりますか?itr>first="";としたらコンパイルできなかったので・・・

253:デフォルトの名無しさん
08/10/29 00:35:55
itr->firstはconstだろが。
なんでそんなことがしたいんだよ!

254:デフォルトの名無しさん
08/10/29 00:39:00
>>252
お前は一度STL標準講座の本を買ってきてサンプルプログラムを
全部手で打ち込んで走らせて実行してみろ。

俺はそうやって覚えた。

255:デフォルトの名無しさん
08/10/29 00:40:34
252の質問はわすれてください!whileでインクリメントしてたitrをbeginに設定しなおしてなかった・・・

256:デフォルトの名無しさん
08/10/29 04:25:30
学習の初期なら、ヘタすりゃ一日100個はつまらん疑問(後から考えれば)が浮かぶもんだが、
その頻度でいちいち書き込まれちゃかなわん。

ていうか、ある疑問を自力で解こうと動く過程で、副作用的に身につく多くの事柄こそが
実質的には学習のメインだと思うんだが(疑問を1つ解決する度に、幾つもの新知識が身につく)、
いちいち質問してたらその一番大事な効能が激減するぞ。

257:デフォルトの名無しさん
08/10/29 06:08:33
至言

258:デフォルトの名無しさん
08/10/29 07:53:27
つか、STL以前の問題ばかりだな

259:デフォルトの名無しさん
08/10/29 08:05:31
>>240
C では int だけど C++ では char 。

260:240
08/10/29 08:55:46
>>242
あほ。
文字列リテラルに文字を突っ込む馬鹿じゃねーよ。
勝手に他人認定するな

261:デフォルトの名無しさん
08/10/29 10:43:00
考えてみろ、と言われても
何も考えず「あほ」呼ばわりする程度には馬鹿なんですね。

262:デフォルトの名無しさん
08/10/29 12:49:34
>>261は何か勘違いをしてないか

263:デフォルトの名無しさん
08/10/29 13:28:07
あほだし仕方がない

264:デフォルトの名無しさん
08/10/29 17:05:21
>>258
だからあのときあれほどC++相談室とスレ分けるなと言ったのに・・・

265:デフォルトの名無しさん
08/10/29 17:08:29
>>264
一緒にしたら荒れて収拾付かなくならなくないか?
C++相談室が過疎ってるから丁度いいのかもしれんけど

266:デフォルトの名無しさん
08/10/29 21:05:44
初心者スレに行くべきだと思う

267:デフォルトの名無しさん
08/10/30 17:12:36
リストの中身をAの順で並び替えて、A同士が連続したままになるように
Bの順で並び替えるにはどうすればいいの?

268:デフォルトの名無しさん
08/10/30 17:17:32
Bでソートした後
Aで安全ソート
ってことか?

269:デフォルトの名無しさん
08/10/30 17:52:56


>>267

あ1 あ2 あ3 い7 い9 う4 う5 う6
てな感じ?

270:デフォルトの名無しさん
08/10/30 22:02:56
>>268
安全じゃなくて安定だろ

271:デフォルトの名無しさん
08/10/31 00:01:29
stable_sort

272:デフォルトの名無しさん
08/10/31 07:46:27
期待通りの並てになるまでランダムに入れ替える

273:デフォルトの名無しさん
08/10/31 07:54:36
きたいどおりのなみて?

274:デフォルトの名無しさん
08/10/31 08:11:40
>>272
ほんとにそういうアルゴリズムがあるんだよな
最初見たときギャグかと思ったが
Wikipedia項目リンク

275:デフォルトの名無しさん
08/10/31 08:54:38
お前らボゴソートさんをあまりなめない方が良い。

276:デフォルトの名無しさん
08/10/31 08:54:40
勿論、ギャグですが。

277:デフォルトの名無しさん
08/10/31 09:48:11
イテレータを保持して参照しようとするとエラーが出る

erase()はしてない、参照前にpush_back()をした
push_back()すると以前のイテレータが無効になるのか?

278:デフォルトの名無しさん
08/10/31 09:52:06
>>277
無効になるコンテナもある。vectorとかdequeとか。
無効にならないコンテナもある。listとかmapとか。

279:デフォルトの名無しさん
08/10/31 12:25:13
まさにvector
場所を保持できないので必要なデータをとるときに
最初から検索しなきゃならないので不便だな
listに変更する

280:デフォルトの名無しさん
08/10/31 12:29:08
vectorなら単にインデクスアクセスすりゃいいんじゃね?

281:デフォルトの名無しさん
08/10/31 12:58:07
インデックスも保持しといたらあてにならんだろう

282:デフォルトの名無しさん
08/10/31 13:13:01
push_backしかしないならインデックスは変わらんだろ

283:デフォルトの名無しさん
08/10/31 15:29:09
インデックスはとある理由で禁書されている。

284:デフォルトの名無しさん
08/10/31 15:45:12
push_backしかしない場合、dequeのイテレータは無効になるが
参照やポインタは無効にならない。

微妙に便利な時もあるかもしれない。

285:デフォルトの名無しさん
08/10/31 16:25:56
push_backしかしない場合インデックスは変わらないだろうけど
参照とかポインタは変わるだろ

286:デフォルトの名無しさん
08/10/31 16:57:59
vectorならな
dequeだと変わらない

287:デフォルトの名無しさん
08/10/31 17:25:06
dequeもメモリ続いてるから、足りなくなったら再確保されてアドレス変わらね?

288:デフォルトの名無しさん
08/10/31 17:48:20
> An insert at either end of the deque invalidates all the iterators to the deque,
> but has no effect on the validity of references to elements of the deque.

先頭と末尾への挿入は、イテレータは無効にするが要素への参照は無効にしない。

289:デフォルトの名無しさん
08/10/31 17:53:24
↑は規格書の 23.2.1.3 deque modifiers のところね。

290:デフォルトの名無しさん
08/10/31 17:53:27
>>287
deque<T>の仕様をとてつもなく乱暴に要約すると、
vector<T*>みたいな構造になってる。
だから拡張されても要素自体のアドレスは変わらない。


291:デフォルトの名無しさん
08/10/31 17:55:25
ちなみに両端以外への挿入はイテレータも参照も無効になるから注意

292:デフォルトの名無しさん
08/10/31 18:37:10
>>287
ランダムアクセスできるだけでメモリは続いてないでしょ?

293:デフォルトの名無しさん
08/11/01 01:17:19
とうとうお前らがdequeのスゴさに気づく時が来た

294:デフォルトの名無しさん
08/11/01 01:20:50
いや知ってて当たり前のことばかりだから

295:デフォルトの名無しさん
08/11/01 01:21:28
dequeの使いどころがわからん

296:デフォルトの名無しさん
08/11/01 01:29:23
上から取ったり、下から取ったり、南京玉簾のような使い方をする場合、dequeほど使えるコンテナは無いぞ。

297:デフォルトの名無しさん
08/11/01 01:49:09
「dequeは結構すげえんだぜ!」
っていうデータをまとめた記事(英語)が以前貼られてたね。

298:デフォルトの名無しさん
08/11/01 09:50:07
>>295
・ランダムアクセスしたい
・要素を加えたり抜いたりすることがある

そういうときに使う。
vectorでやると要素の追加・削除で領域を連続にするためのコストがかかる。

299:デフォルトの名無しさん
08/11/01 11:40:49
listはイテレータを記録すれば、ランダムアクセスできるよね?
イテレータが無効になる場合ある?

300:デフォルトの名無しさん
08/11/01 11:48:27
つうかイテレータ記録すればどんなコンテナだろうとランダムアクセスできるんじゃね

301:デフォルトの名無しさん
08/11/01 12:57:27
話の焦点が「イテレータを記録するモノ(コンテナなり何なり)」の機能に移るだけだよな、それ。

302:デフォルトの名無しさん
08/11/01 14:17:32
>299
結局 vector<list<something>::iterator> みたいなのを使うことになって
vector が登場する罠

303:デフォルトの名無しさん
08/11/01 17:56:00
つまり
boost::multi_index
の話しに

304:デフォルトの名無しさん
08/11/02 00:29:30
dequeのbuffer sizeってなんぼぐらい?

vc7,8は16bytes
gcc3.4.4(cygwni)は512bytes

vcの16って小さくね?
stringなんかはlistと同じになっちゃわないか

このサイズを指定できるdequeがほしいんだが
boostにあったりするかなあ

305:sage
08/11/02 02:27:17
すみませんです。
listのiteratorって、
要素の追加とか削除とかして要素数が変わってしまっても、
そのまま使える保証はあるんでしょうか?
要素の参照は保証されている思うんですが、iteratorが使えるのか。
VCでは実際動くみたいですが言語仕様的にいかがなものか。
ぜひアドバイスおねがいします。

306:デフォルトの名無しさん
08/11/02 02:48:55
保証されている。アドバイスとしては仕様書読め。

307:デフォルトの名無しさん
08/11/02 02:51:24
付け加えると削除したイテレータ自体は当然無効になる。

308:sage
08/11/02 03:15:01
早速の返答ありがとうございます!
ブラボーlist!使いやすさ爆発です。
そして以後ちゃんと仕様書読むようにします。
ありがとうございました。m(_ _)m

309:デフォルトの名無しさん
08/11/02 10:20:03
VC使ってる時点で言語仕様も糞も無いと理解しろ。

310:デフォルトの名無しさん
08/11/02 11:41:22
VC++6.0の頃じゃないんだから
今は結構まともだよ

311:デフォルトの名無しさん
08/11/02 12:10:26
VC++2008と仕様書との相違点はそれほど多くない。
書いてないだけで、これ以外にもあるのかもしれないがw
URLリンク(msdn.microsoft.com)

312:デフォルトの名無しさん
08/11/02 13:37:16
むしろgccのほーが異端

313:デフォルトの名無しさん
08/11/02 13:45:55
それはない

314:デフォルトの名無しさん
08/11/02 14:30:28
MFC(笑)
ATL(笑)

315:デフォルトの名無しさん
08/11/02 15:35:16
急にどうした?

316:デフォルトの名無しさん
08/11/02 15:45:00
dcc最強

317:デフォルトの名無しさん
08/11/02 20:53:06
ecc最強



翻訳的な意味で

318:デフォルトの名無しさん
08/11/04 13:56:24
BCCはどうよ
C++Builder2009にはBoost標準添付だったが

319:デフォルトの名無しさん
08/11/04 14:33:06
Boostって行っても1.35、しかもフルセットでなくてサブセットだけどな

320:デフォルトの名無しさん
08/11/05 11:45:38
map<string int> hoge;

mapを宣言したとき、intの領域は初期化されているんでしょうか?

されていないとしたら、

map<string,int>::iterator itr;
map<string,int>::iterator itrEnd;

itr = hoge.begin();
itrEnd = hoge.end();

while(itr != itrEnd){

itr->second = 0;
itr++;
}


のように初期化すればいいんですかね?

321:デフォルトの名無しさん
08/11/05 11:58:44
ちがう

322:デフォルトの名無しさん
08/11/05 12:00:49
なんで初期化したいんだろうか

323:デフォルトの名無しさん
08/11/05 12:12:16
intのほうでカウントとりたいんです

324:デフォルトの名無しさん
08/11/05 12:33:11
map<string int> hoge;

だけだと map コンテナの中身は空っぽだから
string も int もまだ領域確保されていなくて
デフォルト初期化も値初期化もはじまっていない
空のコンテナの begin() と end() は無効な要素を指している
無効な要素に対するアクセスは失敗する

itr->second = 0; // やっちゃらめぇ

だと思います

325:デフォルトの名無しさん
08/11/05 12:47:23
空のコンテナなら begin() == end() にならないんだっけ?
そうなるなら>>320を走らせちゃってもアクセス違反にはならないが

326:デフォルトの名無しさん
08/11/05 12:51:39
>>324
なるほど

void func(){

map<string int> hoge;

}

の関数内で宣言した場合、関数が呼び出される度に 空っぽになるんでしょうか?

327:デフォルトの名無しさん
08/11/05 13:04:07
呼び出される度にbegin()==end()になります

328:デフォルトの名無しさん
08/11/05 13:16:46
hoge["str"] ++;

とやればちゃんと0から加算されるんですか?

329:デフォルトの名無しさん
08/11/05 13:17:25
空のコンテナのイテレータはbegin()==end()になるって保証は
規格書に書いてあるの?

330:デフォルトの名無しさん
08/11/05 13:18:24
>>328
vectorとmapを混同するな

331:デフォルトの名無しさん
08/11/05 13:19:34
>>328
規格ではmapにoperator[]を適用した場合もしそのキーが
存在しない時はデフォルトのコンストラクタで初期化される
決まりになってるからint()、つまり0から始まる

332:デフォルトの名無しさん
08/11/05 13:22:43
>>329
23.1.7


333:デフォルトの名無しさん
08/11/05 13:25:49
>>330
どの辺を混同していますか?

334:デフォルトの名無しさん
08/11/05 13:25:53
>>332
サンクス
これは目から鱗だ

335:デフォルトの名無しさん
08/11/05 20:23:33
iteratorの位置を動かすとき
++it とかするけど it+=8 のような感じで8個分移動する方法はないの?

336:デフォルトの名無しさん
08/11/05 20:26:55
>>335
advance

337:デフォルトの名無しさん
08/11/05 20:27:32
もちろん、ランダムアクセス可能なイテレータはit += 8で平気。

338:デフォルトの名無しさん
08/11/05 20:36:44
listなのでループで回すしかないか

あと、ある値を持つコンテナを検索する関数を作ったのだが
見つからなかった場合NULLを返そう思ったら
itにNULL代入できない。しかも it ==0とか演算も不可
このような場合みんなはどうしてるん?

339:デフォルトの名無しさん
08/11/05 20:40:21
>>338
end返すのはいやなのか?

340:デフォルトの名無しさん
08/11/05 20:47:32
thx、打開した

341:デフォルトの名無しさん
08/11/05 21:25:09
そもそもfindでいいんじゃね

342:デフォルトの名無しさん
08/11/05 21:28:59
stlportのhash_mapにお尻から回す奴はないですか?

343:デフォルトの名無しさん
08/11/05 21:33:23
イチジク浣腸はどうだ

344:デフォルトの名無しさん
08/11/05 21:53:29
rbegin() rend()

345:デフォルトの名無しさん
08/11/05 22:49:22
叙述関数には引数わたせないの?
find_if( List.begin(), List.end(), compare( 引数1 、 引数2 ) );

346:デフォルトの名無しさん
08/11/05 22:56:09
ファンクタを使えばいくらでも。

347:デフォルトの名無しさん
08/11/06 16:02:53
>>342
vcのstdext::hash_mapならreverse_iteratorがあるぞ

348:デフォルトの名無しさん
08/11/07 00:51:20
VC2008とSTLpらすか5.1.7ですけど
_STLP_USE_STATIC_LIBを指定すると
↓と言われてリンクできません。
ファイル 'stlportstld_statix.5.1.lib' を開くことができません。

stlportstld_static.5.1.libならあるんですけど。バグですか?

349:デフォルトの名無しさん
08/11/07 01:02:22
ren stlportstld_static.5.1.lib stlportstld_statix.5.1.lib

350:デフォルトの名無しさん
08/11/07 01:12:47
#define _STLP_NEW_PLATFORM_SDK 1

351:デフォルトの名無しさん
08/11/08 12:18:23
VB6からVC++2005にプログラムを移植してるんですが、
下記の処理がVB版に比べてVC++版では50倍ほど時間がかかりました。
1から順に使われていないID番号を探すアルゴリズムで、内容は全く同じですが、なぜでしょうか?
m_itemは構造体配列で、要素数は600個程度です。
VC++のstd::vectorの実装はクソすぎなんでしょうか?

■VBの処理

Dim i As Long, j As Long
For i = 1 To 65535
 For j = 0 To m_item_num - 1
    If m_item(j).id = i Then Exit For
 Next
  If j = m_item_num Then
   get_new_item_id = i
   Exit Function
 End If
Next

■VC++の処理

size_t i, j;
for( i= 1; i< 0xFFFF; i++ ){
 for( j= 0; j< m_item.size(); j++ )
   if( m_item[j].id == i )  break;
 if( j == m_item.size() )  return i;
}

352:デフォルトの名無しさん
08/11/08 12:36:59
>>351
const size = m_item.size();
for(j = 0; j < size; ...

キミのままだと、jのループ後とにm_item.size()関数が評価される。

353:デフォルトの名無しさん
08/11/08 12:47:16
VC2005だとm_item[j]が毎回範囲チェックされてる
vector使う前に
#define _SECURE_SCL 0を入れると良い感じらしい

あと、まさかとは思うけどDebug版じゃなくて
Release版で実行してないとかはないよね?


354:デフォルトの名無しさん
08/11/08 12:58:48
そもそもループを1重に直したら(VBでもC++でも)もっと速くなると思う。

355:デフォルトの名無しさん
08/11/08 12:59:39
setでも使えばいいのに、とも思った

356:デフォルトの名無しさん
08/11/08 13:01:24
VBは知らないけど、C++のただの配列とvectorとでも50倍も差はないから、なんか他の要因で遅くなってると思われ。

357:デフォルトの名無しさん
08/11/08 13:02:15
あーごめんそれは無理か

358:デフォルトの名無しさん
08/11/08 14:00:46
終了条件おかしくないか?

359:デフォルトの名無しさん
08/11/08 14:07:46
351ですが、

>>352が主な原因だったようです。>>353でも多少改善しました。
二重ループをやめて、qsort()でもしてから一重ループで探すというのもいいかもしれませんが、
アルゴリズムを変更しないとVBより遅くなるというのは腑に落ちませんね。

ベクターは使い方次第でパフォーマンスに劇的に影響するようで、なんか怖いです。

360:デフォルトの名無しさん
08/11/08 14:24:53
VC2008のvectorで
if (int i = 0; i < tbl.size(); i++) tbl[i] ・・・
みたいな使い方と、
配列で、
if (int i = 0; i < TBL_SIZE; i++) tbl[i] ・・・
みたいな使い方をした場合、
Debugビルドで最適化なしだと数十倍の差で、Releaseビルドで、最適化ありだと、二倍程度の差だった。

361:デフォルトの名無しさん
08/11/08 14:26:01
このスレ的にはiterator使おうぜ

362:デフォルトの名無しさん
08/11/08 14:31:04
>>359
VB知らないんだけど、この場合のm_item_numってなに?
それ次第では、そもそも「内容は全く同じ」という認識が間違ってたことに。

363:デフォルトの名無しさん
08/11/08 14:35:47
VBとコードが違わないか?
>for( i= 1; i< 0xFFFF; i++ ){
for( i= 1; i<= 0xFFFF; i++ ){

調べてる要素が違ってるなら50倍違ってもおかしくはないけど。
あとは計測時間が短すぎて時間を計ってるタイマーの精度の違いが出てるとか
とりあえず>>351のコードをReleaseビルド&_SECURE_SCLでコンパイルしてVBより50倍も遅いなんてことあり得ないだろ。

364:デフォルトの名無しさん
08/11/08 14:53:51
>359
ちゃんと最適化かけたか?

365:デフォルトの名無しさん
08/11/08 15:06:10
STLがVBに負けるなんて悔しい ビクンビクン

366:351
08/11/08 15:08:04
すみません。デバッグビルドになってたようです><
なんかデバッグなしにしたり最適化とかするとエラーが出てコンパイルできなかったので、何となく諦めてました。
>>359をやった上で最適化まですると、VBより速くなりました。
めでたしめでたし。

367:デフォルトの名無しさん
08/11/08 15:10:02
しね

368:デフォルトの名無しさん
08/11/08 15:12:42
まさにVB脳

369:デフォルトの名無しさん
08/11/08 15:14:42
二重ループのかわりにstd::find_ifを使ってみようぜ!
あと上で言ってる人もいるけどsortするならむしろstd::vectorのかわりにstd::setを使おうぜ
Itemがidをもつぐらいなら用途にあってる可能性高いし


370:デフォルトの名無しさん
08/11/08 15:20:36
VBでもデータ構造を変えれば劇的に速くなるな。

371:デフォルトの名無しさん
08/11/08 15:27:41
>>369
ちょっとよく分かりませんが、勉強してみます。
今はVBのコードをC++にツラツラ置き換える作業だけをやってます。

VBの配列 → std::vector
VBのString → std::string

という置き換えで、今のところこれ以上のSTLの知識はありません。
アルゴリズムを下手に変えると、新たにバグが混入することになるので。

372:デフォルトの名無しさん
08/11/08 15:33:36
VB6と一緒に心中してくれよ。こっちくんな。

373:デフォルトの名無しさん
08/11/08 15:40:28
移植させてもらえるだけでも素晴らしいことだと思わないか。

374:デフォルトの名無しさん
08/11/08 15:44:24
つうか既にバグ混入しててワロタ
>for( i= 1; i< 0xFFFF; i++ ){

375:デフォルトの名無しさん
08/11/08 16:03:45
findを使って作ってみました

enum { N = 600, ID_MAX = 0xffff };

template<typename ID> struct Compare {
Compare(ID i) : m_i(i) {}
template<typename T> bool operator()(T const& i) { return i.id == m_i; }
private:
ID m_i;
};

template<typename ID, typename Container>
ID find_uniq_id(Container const& m) {
typename Container::const_iterator m_end = m.end();
for (ID new_id = 1; new_id <= ID_MAX; ++new_id) {
if (std::find_if(m.begin(), m.end(), Compare<ID>(new_id)) == m_end)
return new_id;
}
throw std::domain_error("new_id must not be beyond ID_MAX");
}


376:375
08/11/08 17:05:13
id_typeとget_idを特殊化することによってより流用できるようにしてみました
参照の参照が怖いのと面倒臭いのが難点だと思いました

template<typename T> struct id_type { typedef typename T::id_t type; };
template<typename T>
typename id_type<T>::type get_id(T const& x) { return x.id; }
template<typename T>
struct Comparator {
typedef typename id_type<T>::type ID;
typedef bool result_type;
Comparator(ID i) : m_i(i) {}
bool operator()(T const& i) const {
return get_id<T>(i) == m_i; }
private:
ID m_i;
};
template<typename ID, typename Container>
ID find_uniq_id(Container const& m) {
typename Container::const_iterator m_end = m.end();
for (ID new_id = 1; new_id <= ID_MAX; ++new_id) {
if (std::find_if(m.begin(), m.end()
, Comparator<typename Container::value_type>(new_id)) == m_end)
return new_id;
}
throw std::domain_error("new_id must not be beyond ID_MAX");
}

377:デフォルトの名無しさん
08/11/08 17:39:34
これはひどい

378:デフォルトの名無しさん
08/11/08 18:08:48
なんというオナニー

379:デフォルトの名無しさん
08/11/09 02:37:20
数値を文字列にするには
ostringstream を使用する方法がメジャー?

380:デフォルトの名無しさん
08/11/09 02:39:59
>>379
たぶん sprintf を使う人のほうが多い。
snprintf が C++ 標準に入ればさらに増えるかもしれない。

結果を string で使うことや安全性を考えれば ostringstream のほうが良いとは思うけど。

381:デフォルトの名無しさん
08/11/09 02:54:15
sprintfはchar確保するの面倒だとおもうけど
利用者が多いのは何か理由があるの?

382:デフォルトの名無しさん
08/11/09 02:55:45
>>381 C からの移行組。

383:デフォルトの名無しさん
08/11/09 03:10:24
Exceptional C++ Style でstringstreamはsprintfに比べて
だいたい10倍くらい遅いと書かれていた。

384:デフォルトの名無しさん
08/11/09 03:30:02
速度的な点もあるけど
printf系というのは非常に多くの言語で(Win32にはAPIもある)用意されていて
細部の違いはともかく、知っている人が多い、使い方を覚えて無駄にならない、
というのもある。

C++だけの世界だけで見れば型安全性の無さ等非難される面も多いし
「C++らしくない」という良くわからない理由で嫌う人も。
また、(よく知らない人に多いが)セキュリティ等の面で問題があると言い張る人も居る。

385:デフォルトの名無しさん
08/11/09 03:54:57
書式の設定がめんどくさい上に、長くなってしまう気がするんだが俺の書き方悪いのかな

386:デフォルトの名無しさん
08/11/09 04:07:58
>>385
stream のことなら、たぶんそんなもん。

そういえば C++0x でもこの点は特に改善されたような話を聞かないな。
boost の io state saver ぐらいは入ってもよさそうなもんだと思うけど。

387:デフォルトの名無しさん
08/11/09 10:57:41
>>379
boost::lexical_cast を使うがよい
結局 stringstream 使ってるんだけどな

388:デフォルトの名無しさん
08/11/09 11:53:14
>>381
char確保しなくてもいいよ。

std::string str;
int a = 123;

str.resize(256,0);
sprintf((char*)str.c_str(), "%d", a);
str = str.substr(0, str.find('\0'));


389:デフォルトの名無しさん
08/11/09 12:04:57
stringにconst_castか…

390:デフォルトの名無しさん
08/11/09 12:06:07
c_strの間違いw

391:デフォルトの名無しさん
08/11/09 12:23:41
>>388
c_str() の戻り値に無理やり書き込んでも反映されるとは限らんよ
っていうかconst外して書き込むなんて無茶苦茶にもほどがある

392:デフォルトの名無しさん
08/11/09 12:24:08
#include <vector>
#include <cstdio>
#include <iostream>

int main(int, char *[])
{
std::vector<char> buf(0xff, 0);
int n=10000;
std::sprintf(&buf.front(), "%d", n);
std::cout << static_cast<const char*>(&buf.front()) << std::endl;
return 0;
}

なるへそ

393:デフォルトの名無しさん
08/11/09 12:27:03
printf系はセキュリティ面で問題あると思ってたが

問題ないの?

394:デフォルトの名無しさん
08/11/09 12:29:46
const外し
か、漢だ!

395:デフォルトの名無しさん
08/11/09 12:30:56
nの型がintでlog10(n)が100や200にもなるアーキテクチャがあれば教えて欲しいものだ

396:デフォルトの名無しさん
08/11/09 12:41:02
string使おうがvector使おうが
スタック上に領域確保してれば
char配列となんら変わらん

397:デフォルトの名無しさん
08/11/09 12:46:24
>>396
大概はそうだが、規格には反するな

398:デフォルトの名無しさん
08/11/09 13:07:49
>>393
使い方の問題。
ユーザー入力をフォーマット文字列に使おうとする大バカと
最大文字数の指定方法を知らないバカがそう言ってるだけ。

399:デフォルトの名無しさん
08/11/09 13:18:32
>>398
具体的に何の関数を言ってるかわからんけど、
すくなくともsprintfはあぶない

400:デフォルトの名無しさん
08/11/09 13:28:49
一般的にやるべきでないとされていることを「だって出来るじゃん」の一言でやってしまう・・・

くせぇーっ! DQN以下の臭いがぷんぷんしやがるぜぇーっ!

401:デフォルトの名無しさん
08/11/09 13:31:44
>>399
具体的にどこが危ないのか教えてよ

「使い方を間違えたら危ない」というレベルの話なら
「listen()を使う全てのプログラムは危ない」というのと同じになっちゃうから

402:デフォルトの名無しさん
08/11/09 13:39:40
>>401
え?最大文字数を指定できないじゃん

それが危険だと思えないならまぁ好きにするといいよ

403:デフォルトの名無しさん
08/11/09 13:42:38
sprintfで100byteのバッファしか取っていないのに、
100文字以上有るかもしれないユーザ入力を与えるとかね。

404:デフォルトの名無しさん
08/11/09 13:44:11
VCのsprintf_s使ってます(^^)

405:デフォルトの名無しさん
08/11/09 13:46:22
ハア?

char buff[100]
sprintf(buff, "%.80s", user_input);

これのどこが危ないって?

406:デフォルトの名無しさん
08/11/09 13:47:28
まさしく>>398の最下行に書いてあるバカが言ってるとしか思えないんですけど。

407:デフォルトの名無しさん
08/11/09 13:48:08
C++ で何で sprintf なんて使ってるのん?
しかも STL スレで・・・。
ostringstream か boost::format を使っとけ。

408:デフォルトの名無しさん
08/11/09 14:00:20
>>405
そういうことを分かって使う分にはいいけど、
実際に使う人間が必ずしも分かっているとは限らないし、
分かっていても、うっかりやってしまう危険性があるよね。

409:デフォルトの名無しさん
08/11/09 14:04:25
つうかそんな単純なケースならいいけど、
色々出力したりロケールが絡むと出力結果の予想がしんどいだろ

410:デフォルトの名無しさん
08/11/09 14:08:01
そんなレベルなら、「vectorで[]は使わないほうが良い。at()を使え。」と同じじゃないの。

特に>>399はわざわざ>>398に対して言ってるんだから
もっとちゃんとした危険性を指摘してくれても良さそうなもんだけど。

そりゃ、切捨て前提という仕様は良くないとか
全部生かすつもりならsnprintfの方が楽だとか言うのはその通りだけど
それとセキュリティ的な問題は全く別だから。

柔軟性だって例えば
std::vecotr<char> buff;
buff.resize(???);
sprintf(&buff[0], "%.*s", buff.size()-1, str);
のような使い方である程度確保できるし。

>>409
「使いやすさ」と「セキュリティ的に問題」は全く別の話なんですけど。

411:デフォルトの名無しさん
08/11/09 14:13:43
>>410
> 「使いやすさ」と「セキュリティ的に問題」は全く別の話なんですけど。
この一行が>>409の話とは全く別の話なのは、そういうジョークなの?

412:デフォルトの名無しさん
08/11/09 14:14:33
ostreamが状態を持ってるのもしんどい

413:デフォルトの名無しさん
08/11/09 14:14:53
あ、別にユーザー文字列をそのまま配列に落とす場合に限らないよ。

そもそも(1箇所での)ユーザー入力なんて、普通は1つなんだから
例えば
sprintf(filename, "file-%.80s%d.dat", input, num);
のような形式でも、充分に最大値は予想できるし。
あ、「intが512bitの環境を考慮すると面倒」というのはその通りか。

414:デフォルトの名無しさん
08/11/09 14:17:55
使い難さが有るということは、ミスり易いってことじゃね?
ミスってもセキュリティ的な問題が出ないライブラリならいいんだけど。

415:デフォルトの名無しさん
08/11/09 14:19:43
いわゆる、バグというものは、ミスることによって起こるんだから。
十分予想出来るとかで大丈夫じゃないか、なんていい方出来るだったら、
世の中の全てのソフトウェアにはバグが無いってことも言えてしまう。

416:409
08/11/09 14:19:58
>>410

いやだから
出力結果の予想が困難→バッファ長の予想が困難
セキュリティ的にあぶなくね?
という話し

気をつけて使え
って話しなら
そうですね
としか言えないけど

みなミスりがちだからsnprintfとかVC++のセキュア関数とか
あるんじゃないの?

417:デフォルトの名無しさん
08/11/09 14:32:40
いやだから
全然>>398への反論になってない。
「使い方を知らないのが問題」なだけでは
「セキュリティ的に問題がある」ということにはならないから。
まあ、416の言いたいことはもっともだし
他にもっと良い選択肢があるならそちらを使うべきなのは確か。
でも残念ながら標準ではない。


ただ、自分が「使い方を知らないバカ」だという自己紹介はもういいよ。
>>398の最下行を無視して>>402と反論するような人が>>399みたいに書くわけだから。

418:デフォルトの名無しさん
08/11/09 14:35:28
あ、それと、「最大値の見積もりを間違える」点についてだけど

別に用意したバッファの95%以上まで使わなければいけない、というような決まりはないから。
多少(例えば末端の'\0'とか)の計算ミスがあっても充分すぎるように見積もって置けばよい。
例えば>>405のようにね。

419:デフォルトの名無しさん
08/11/09 14:37:36
>多少(例えば末端の'\0'とか)の計算ミスがあっても充分すぎるように見積もって置けばよい。
ええええー

420:デフォルトの名無しさん
08/11/09 14:38:20
最大量がきっちり分かってる状況じゃないかそれでいけるのは

421:デフォルトの名無しさん
08/11/09 14:41:24
は?
当然過ぎて困りますが
ユーザー入力の部分の最大量は>>405のように制限して
その上で他の部分の見積もりが多少違っていても大丈夫なように
ということですけど。

422:デフォルトの名無しさん
08/11/09 14:42:37
ユーザー入力の部分の最大値を制限するのは
当然というか大前提だと思っていましたが、皆さんは違うのですか。
認識の違いですね。

423:デフォルトの名無しさん
08/11/09 14:44:22
つまり、%fは使うなってことですね、判ります。

424:デフォルトの名無しさん
08/11/09 14:48:54
あー、sprintfは使い方が難しくセキュリティ的な問題を起こしやすいので使うべきではない。
とすると、

同じように、
使い方が難しくセキュリティ的な問題を起こしやすいものは使うべきではない
ということになりますね。

つまり、
C++をやめましょう、と。
Javaあたりがよろしいでしょうか。
実際、世間の潮流もそういう流れになってますしね。

425:デフォルトの名無しさん
08/11/09 14:49:50
>>423
%.fを使ってください

426:デフォルトの名無しさん
08/11/09 14:52:52
>>425
sprintf(buf, "%10.0f", 1e100);

427:デフォルトの名無しさん
08/11/09 15:02:23
snprintf()なら、
snprintf(s, sizeof(s), …
ってやっとけば安全だけど、
sprintf()は人間が数えないといけないじゃん。

>>405 見たいな単純なやつだったらどっちでもいいってことになるかもしれんけど、
書式が複雑になってくると、ミスる可能性がでてくるよ。

てか単純にsnprintf()のほうが楽ジャン。sprintf()で人間がバッファサイズ数えるなんて非合理。

428:デフォルトの名無しさん
08/11/09 15:04:36
いつまで STL スレで sprintf の話をやってんだよ。
そんな型安全じゃない C の糞遺物なんぞ C++ で使うな。

429:デフォルトの名無しさん
08/11/09 15:05:04
だよな!

430:デフォルトの名無しさん
08/11/09 15:07:32
>>426
printf("%.2u", -1);
の時に必ず2桁に収まると思う人は居ませんね。
これと同様に最大桁数が見積もれる点は変わらないと思いますが。
いや、最大桁数はbit数に依存するので環境依存ですけど。

>>427
だからsnprintfはC++においては非標準だって。
それに「sprintfはセキュリティ的に問題がある」という意味にはならないよ。
「C++はセキュリティ的に問題がある」というのと同様。

431:デフォルトの名無しさん
08/11/09 15:07:47
ところで型安全って何ですか?

432:デフォルトの名無しさん
08/11/09 15:10:57
snprintfってC99からなんだっけ…
0xでは標準になるのかなぁ

433:デフォルトの名無しさん
08/11/09 15:12:10
なりません

434:デフォルトの名無しさん
08/11/09 15:13:40
相変わらず話題の質が下がると賑わうな。

435:デフォルトの名無しさん
08/11/09 15:20:11
>>432
ドラフト N2798 の 17.1 [library.general] p9 より
> This library also makes available the facilities of the C99 standard library,
> suitably adjusted to ensure static type safety.

436:デフォルトの名無しさん
08/11/09 15:23:46
_scprintfで数えたらいい

437:デフォルトの名無しさん
08/11/09 15:28:25
>>430
doubleの最大桁数を常に見込んでバッファを確保するとでも?
%fを使わずに、素直に%gを使えば済むじゃん。
そういう使いこなしを必要とするからsprintf()は難しいと言うなら判るが、
使いこなしてもいないのに語ろうとするな。

438:デフォルトの名無しさん
08/11/09 15:33:24
結論:ostrstream or boost::lexical_cast or boost::format or boost::egg::to_string

439:デフォルトの名無しさん
08/11/09 16:00:48
結論:いままで聞いた話を総合すると、一番スマートなのはこれ。

std::string str;
int a = 123;
str.resize(12);
sprintf_s((char*)str.c_str(), str.size()-1, "%d", a);
str.resize(str.find('\0'));

ストリームとかで中間バッファを使うのはメモリの無駄だし、sprintfの書式指定能力の高さは最強。

440:デフォルトの名無しさん
08/11/09 16:02:21
>>439
その場合だとstr.size()は0が返るよ。
あと規格は大切にね。

441:デフォルトの名無しさん
08/11/09 16:03:16
>>その場合だとstr.size()は0が返るよ。
ごめん勘違いした。

でもその書き方は受け入れられない。

442:デフォルトの名無しさん
08/11/09 16:05:42
c_str()を出力バッファに使う男の人って

443:デフォルトの名無しさん
08/11/09 16:06:48
もはやSTLじゃねーなw

444:デフォルトの名無しさん
08/11/09 16:13:28
vectorを使えばかろうじてSTLに関する話題の範疇に入…らないか

445:デフォルトの名無しさん
08/11/09 16:17:17
>>439
× (char*)str.c_str()
○ &str[0]

あと、せっかくだから sprintf_s() の戻り値使えよ。

446:デフォルトの名無しさん
08/11/09 16:30:07
>>445
規格ではstd::stringのメモリ上の連続性は保証されていない。
std::vectorと混同するな

447:デフォルトの名無しさん
08/11/09 16:33:39
どうせ大丈夫なんだから別に良いじゃん


448:デフォルトの名無しさん
08/11/09 16:35:47
仕事で一緒にならないなら別にいいよ

449:デフォルトの名無しさん
08/11/09 16:38:17
>>446
C++0x で連続性は保証されるようになるし、
現状のどの実装でも連続性は成り立っている。

450:デフォルトの名無しさん
08/11/09 16:41:45
>>446
URLリンク(www.open-std.org)
まぁ現時点で保証が無いというのは確かなんだけどね。

451:デフォルトの名無しさん
08/11/09 17:38:58
size_t count = _sctprintf(_T("%d"), 777) + 1;
std::vector<TCHAR> buffer(count);
_stprintf_s(&buffer[0], count, _T("%d"), 777);


452:デフォルトの名無しさん
08/11/09 17:52:09
TCHAR(笑)

453:デフォルトの名無しさん
08/11/09 18:42:07
>>449
そういう話をしたいのなら実装依存スレへ逝け

454:デフォルトの名無しさん
08/11/09 18:43:16
>>451
そういう話をしたいのなら実装依存スレへ逝け

455:デフォルトの名無しさん
08/11/09 19:54:23
STLのlistを利用したプログラムを実行中、
"list iterators incompatible" という例外が発生しました。これはどういったエラーでしょうか?
開発環境はVisualStudio2005 AcademicEditionです。

456:デフォルトの名無しさん
08/11/09 20:01:13
ソース晒せ

457:デフォルトの名無しさん
08/11/09 20:06:15
transformの使い方に関して質問があります。環境はGCCです。
目的は、stringの中身をすべて小文字に変換したいのです。

#include <string>
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <iostream>

string aa = "AbCdEfG";
transform(aa.begin(),aa.end(),aa.begin(),tolower)

で、aaの中身をすべて小文字に変換できません。
理由はわかりますでしょうか?

458:デフォルトの名無しさん
08/11/09 20:10:50
>>457
とりあえずコンパイルエラーだろ。
エラーの意味がわからんということならエラーメッセージ晒せ。

459:デフォルトの名無しさん
08/11/09 20:14:20
俺の環境では全部小文字になるが・・・。

460:デフォルトの名無しさん
08/11/09 20:20:44
使用したソース

#include <string>
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <iostream>
using namespace std;
int main(){
string aa = "AbCdEfG";
transform(aa.begin(),aa.end(),aa.begin(),tolower);
}

以下がコンパイルエラー

test.cpp: In function 'int main()':
test.cpp:9: error: no matching function for call to 'transform(__gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits\
<char>, std::allocator<char> > >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> \
> >, __gnu_cxx::__normal_iterator<char*, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, <unresolved overloaded f\
unction type>)'


よろしくどうぞおねがいします。

461:デフォルトの名無しさん
08/11/09 20:23:26
>456
URLリンク(www.hsjp.net)
本来の拡張子は.hppです。ごちゃごちゃしててすみません。
103行目のupdate_etc()関数が怪しいと思っているのですが…

462:デフォルトの名無しさん
08/11/09 20:24:53
Effective STL に乗ってたネタかな

463:デフォルトの名無しさん
08/11/09 20:32:13
>>457
たぶん、こういう関数オブジェクトを作ってそれを渡せばいいよ。
struct my_tolower : std::unary_function<char, char>
{
char operator ()(char c) const
{
return std::tolower(c);
}
};

464:デフォルトの名無しさん
08/11/09 20:54:01
transform(aa.begin(), aa.end(), aa.begin(), static_cast<int(*)(int)>(tolower));
通った

typeof(aa)::value_type : char
tolower : int(*)(int)
でtolowerをchar(*)(char)と型推論しようとして失敗してる

なので正確にキャストして与えてやればおk?

465:デフォルトの名無しさん
08/11/09 20:57:12
>>461
まずはデバッガのバックトレースを見たりブレークポイントつかったりしてあたりつければいいよ
segvだろうが、unhandled exceptionだろうがどこで発生したか分かるから


466:デフォルトの名無しさん
08/11/09 21:00:18
>>464
>>460の最後の行の中にunresolved overloaded function typeってのがあるでしょ。
C++では、tolowerが多重定義されているのだが、
それではテンプレート引数の型が決定できないということでエラーになる。
だから、>>464のようにキャストが必要になる。>>463みたいに他の方法も考えられる。

467:デフォルトの名無しさん
08/11/09 21:06:27
>>466
>>464
>>460
ありがとうございます。
なるほどよく分かりました!


468:デフォルトの名無しさん
08/11/09 21:21:38
>465
ありがとうございます。とりあえずどこで投げてるのか絞り込んでみます。

ただ、list iterators incompatibleというのがどういう状態を指すのか、よくわからないのです。

469:デフォルトの名無しさん
08/11/09 21:37:51
vcのstlのincludeディレクトリにて"list iterators incompatible"で全文検索するとか

470:デフォルトの名無しさん
08/11/09 22:01:54
>469
そういう方法もあるのですね
listの中を覗いてみます。
ありがとうございます

471:デフォルトの名無しさん
08/11/12 11:38:03
dequeにpush_backで要素を挿入していくのは、予め配列をサイズ決め打ちで宣言して代入していくのより遅いですか?

472:デフォルトの名無しさん
08/11/12 12:13:18
>>471
速度は実測が基本。

一般的に、 push_back() を繰り返す場合、配列要素のメモリ確保回数が増えるので
遅くなる可能性が高くて、それでも push_back() ならコピーコンストラクタが使われるので
要素の型によっては代入に比べて速い可能性もある。

473:デフォルトの名無しさん
08/11/12 20:00:12
気になるけど図るのが面倒臭いなら、reserveしておけば精神的に気が和らぐ。

474:デフォルトの名無しさん
08/11/12 22:12:15
vectorならreserveは必須だと思う
dequeってどうだろう

475:デフォルトの名無しさん
08/11/12 22:21:59
dequeはある一定の長さのブロックが不連続に確保されるそうだから
reserveしたらシステムからメモリを持ってくる時間は稼げるけどvector
と違ってメモリの再配置は起きにくいんだよね

476:デフォルトの名無しさん
08/11/12 23:24:27
それは実装によるんでは。

477:デフォルトの名無しさん
08/11/12 23:32:37
実装によるのはもちろんだが一般的な実装の話ね

478:デフォルトの名無しさん
08/11/13 01:13:27
dequeのpush_backが(償却じゃなくて正真正銘の)定数時間であることは規格で要求されてたはず
だから一概に実装に依るとも言えない


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

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