1 :デフォルトの名無しさん:04/12/27 05:23:44
STL(あるいはboost)を使っていく上で
思わぬ落とし穴、やってはいけない禁じ手などを
晒すためのスレです。暗黙知の解放!


15 :デフォルトの名無しさん:04/12/28 00:16:50
stringの参照渡しではなく、実体渡しってコスト高いのかな・・・

例えば、1000文字程度の文字列が格納されてるstringを関数の引数などで
実体渡しだとか、返却すると高いのかな?

string tail( string a)
{
return a + ":addtail";
}

みたいなコード。
参照渡しって微妙に使いにくいんだよね・・・だから実体渡しにしたいの
だけど。


20 :デフォルトの名無しさん:04/12/28 05:20:05
便乗して自分も質問・・・
vector< string > なんかを返却するのは危険だろうか?
例えばの用途としては、ファイル名を列挙するサービスを作ったとして、
その場合、なんらかの形で配列を返しますけど、安全性考えるなら
vectorだとか使いたいところ。それも、返却で。

アセンブリリスト出力させても、いまいち分からないし。
特にSTL内部の謎シンボルにcallだとかjumpされるともう追えない (;-;)


22 :デフォルトの名無しさん:04/12/28 05:27:16
逆落とし穴?ってとこかな。有名だけど、一応足跡残しとこうかな。

vector<>ってアドレス的に連続性が保障されてるって、みなさん
知ってました?

例えば、vector< char > tbl;
とあって、tbl.size()==nな場合、
tbl[0]からtbl[n-1]は連続したアドレスであることが保障されてるんだってさ。STLの仕様として。

なので、char*p = &tbl[0] とかやって、その後は *p++ = 0x00 だとかで
アクセスできてしまうと。iteratorを使う必要もないみたい。

でもdequeでは、保障されてるのか、保障されてないのか不明。
明記された文書も見たこと無い。
listあたりだと確実に連続してないので、気にならないけど
dequeは気になるなー。


56 :デフォルトの名無しさん:2005/06/04(土) 16:50:44
>>22
内部の実装はべた配列だ。だからといってメモリのアドレスを取得して(
そもそも iterator がポインタだったする)vector にアクセスするのは間違いだ。
社会に出たらやっていいことと悪いことを見分けなければならない。
内部のメモリポインタを取得して操作したいのなら valarray を使おう。
単純なループをまわすとき iterator を使おうが [] でアクセスしようが、
ポインタを使ったときと同じ速度のコードをはいてくれる。
今時ポインタのほうが速いというのはうそだと思っていいだろう
(もちろんレジスタの割り当てを気にするくらいの限界のチューニングをするときは違うかもしれないが)。

http://www.nantekotta.com/stl.html

58 :デフォルトの名無しさん:2005/06/04(土) 16:59:35
>>56
vector のメモリレイアウトはC言語の組み込み配列と同じだよ。
そんなメンテナンスされてない古い記事引用して何が言いたいの?

65 :デフォルトの名無しさん:2005/06/04(土) 18:23:57
Cに渡すときはポインタと個数を渡すから
ベクタが空でも、個数も0なんで
結局安全なケースがほとんどだと思うが

66 :デフォルトの名無しさん:2005/06/04(土) 18:25:51
>>65
C/C++使うんなら未定義動作に気をつける覚悟を持たなくちゃ。

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用でいいカエラ!


85 :デフォルトの名無しさん:2005/06/05(日) 06:28:09
>>84
> iterator i = const_cast< const_iterator >( ci );
これ、何がしたいの?

> const_castのオーバーロード関数
これも意味がわからん。

86 :デフォルトの名無しさん:2005/06/05(日) 07:09:42
>>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 ){ ...}

これが全コンテナにあったら便利じゃん。

89 :デフォルトの名無しさん:2005/06/05(日) 08:38:14
iteratorをmutableメンバ変数として持たなければならない時とか


90 :デフォルトの名無しさん:2005/06/05(日) 13:24:21
>>89
mutable iterator って宣言すればいいだけじゃない?
const_cast の出番がわからん。

127 :デフォルトの名無しさん:2006/03/29(水) 15:13:00
いや、次要るから。

128 :デフォルトの名無しさん:2006/03/29(水) 15:22:14
[要らない理由]
STLは規格により明確にC++である
C++相談室と分けるほどトラフィックもない(ってか閑散としてる)
もし分けるとなるとC++相談室では「C++からSTLを除いたもの」を主な話題とすることになるが
「C++からSTLを除いたもの」でそんなに話題あるかい?

>>127
要る理由は?


178 :デフォルトの名無しさん:2007/09/15(土) 15:28:39
ちょっとお聞きしたいのだが
typedef struct tagTestData {
int num;
std::queue<int> que
} TestData

とかやって

TestData *ptr = malloc(sizeof(UserData))

ptr->que.push(1)

とやると,プログラムが落ちるのだが,これってnewじゃないと
だめ?
STLってコンストラクタとか使ってるの?

すごい馬鹿な質問でごめん

191 :デフォルトの名無しさん:2007/09/16(日) 11:45:11
184じゃないけど、バイナリファイルを読み込むときに new char [] は不自然かと思い、malloc() を使ってる。
テキストファイルのときは new char []。

244 :デフォルトの名無しさん:2008/03/17(月) 13:25:17
>尚のこと

で、
何で、

>グローバル関数

グローバルという最悪解がでるんだよ。

がいきち?

247 :デフォルトの名無しさん:2008/03/17(月) 13:40:02
>>244
俺はvectorを継承してメンバ関数を追加するより
vectorを引数に取るグローバル関数を追加するほうがまだマシだと思っている。
五十歩百歩とか言うなら、そりゃそのとおりだ。

258 :デフォルトの名無しさん:2008/03/17(月) 17:16:53
> 完全誤読
そんな四字熟語はありません。

261 :デフォルトの名無しさん:2008/03/17(月) 17:47:46
では何故、いきなり>258のようなことを言い出したのですか?

278 :デフォルトの名無しさん:2008/03/19(水) 22:20:13
STL のコンテナは仮想デストラクタ持ってないから public 継承は危険だな。
protected/private 継承ならマシではあるが。

まあそれはおいといて、コンストラクタはどうしようもないと思う。

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やったら危険ですか?



324 :319:2008/05/19(月) 12:19:47
レスサンクス。

vtblつきのクラスはともかく、
C言語な構造体のvectorは問題ないと思ってmemsetしてた。

一見問題なく動くから困る。今から直します。

327 :デフォルトの名無しさん:2008/05/19(月) 18:24:49
>>324
そもそもstringはあんたの言う「C言語な構造体」には該当しないと思うのだが。

328 :319:2008/05/19(月) 19:05:30
>>327
あいまいな表現で申し訳ない。

aaaのmemsetはセーフだけど
bbbは不味いだろという指摘を期待して質問してしまいました。

「C言語な構造体」というのはPOD型構造体のつもり。
専門用語の厳密な知識が足りないので、あいまいな表現を選択しました。
(aaaをPOD型構造体にしておけばより良かったか)




329 :デフォルトの名無しさん:2008/05/19(月) 20:41:32
>>328
vector<int>もvector<string>もPODではない。
ゆえにTestもPODにならない。

330 :319:2008/05/21(水) 12:11:22
>>329
了解。
C++の仕様をまともに読んだことがなかったから、読んでみるよ。
図書館で『C++ランゲージ クイックリファレンス』借りてきた。


355 :デフォルトの名無しさん:2008/08/31(日) 08:06:22
デフォルトコンストラクタでnewしてコピーコンストラクタで適切にケアして無いのが異常。
そんなクラスを収容できるようにはコンテナはできてないということ。

356 :デフォルトの名無しさん:2008/08/31(日) 11:45:43
>>355
え?コピーコンストラクタを実装するのって暗に当たり前だって言ってる?

悪いけど俺にそんな認識はないなぁ・・・つか無かったなぁ
エラーもでないし
はぁ・・・わかりにく・・・これだからテンプレートって使わない人多いんだろうなぁ・・・

ってちょっと思った

367 :デフォルトの名無しさん:2008/08/31(日) 13:15:03
本人は最後まで「vectorに格納する場合に生じる現象」として捉えていたけど、
MyClass hoge, fuga;
hoge = fuga;
だけでも、なんか素敵なことが起きかねないよな、現状のスキルだと。

379 :デフォルトの名無しさん:2008/08/31(日) 15:45:05
これ、vectorテンプレートを作った奴の評価としてはNGだろ?
現状そうなってるから仕方ないってのは受け入れた上での評価だけど

だってこんな仕様にしたらMyClassを変更するたびに
MyClassの仕様として正しい正しくないの他に
MyClassを使用している箇所を片っ端から探して
newを使用していいかどうか確かめなきゃいけないってことだろ?
最悪じゃね?

カプセル化が完全に死んでるじゃん

380 :デフォルトの名無しさん:2008/08/31(日) 15:47:18
>>379
何度も言われているが、これは vector じゃなくて C++ 一般の話。

383 :デフォルトの名無しさん:2008/08/31(日) 15:52:49
>>380
俺はそうは思わないな
vectorの仕様によっては助かるように細工することもできるわけだし
使用者がvectorの内部まで知らないと使えないってのはやっぱりわかりにくいと思うよ

っていうかコピーコンストラクタの用意されて無いクラスを
vectorにぶち込んだ時点でエラーでもいいと思うけどね

385 :デフォルトの名無しさん:2008/08/31(日) 15:56:47
>>383
> vectorの仕様によっては助かるように細工することもできるわけだし
どうやって?

コピーコンストラクタの用意されてないクラスをエラーにすると、 C の構造体が
vector に入れられない。それは面倒だ。

387 :デフォルトの名無しさん:2008/08/31(日) 16:00:17
>>385
クラスがきたときだけptr_vector仕様にする

399 :デフォルトの名無しさん:2008/08/31(日) 16:35:03
要は、危険なクラスをコンテナだけが安全に使えても意味がないということなんだが。
何でそんな簡単なことも判らないでこのスレにいるんだ?

400 :デフォルトの名無しさん:2008/08/31(日) 16:37:12
>>399
えー意味わからん
危険なクラスってコピーコンストラクタがないクラスを言ってるの?

402 :デフォルトの名無しさん:2008/08/31(日) 16:49:58
>>400
必要なコピーコンストラクタを欠いているクラスが危険だと言っている。

403 :デフォルトの名無しさん:2008/08/31(日) 16:51:35
いや、要件を満たしていないのに使えてしまうのが危険なんだよ。

404 :デフォルトの名無しさん:2008/08/31(日) 16:56:56
>>402

意味分からん

>要は、危険なクラスをコンテナだけが安全に使えても意味がないということなんだが。
この発言だと
vectorにつっこんだときのことを言ってるんじゃなくて
MyClassが危険なクラスって言いたいんだよね?

でも

>必要なコピーコンストラクタを欠いているクラスが危険だと言っている。

こんなこというからさっぱりわからないよ
何が言いたいの?

>>403
俺もそう思うな
望ましい状態は2つあって使えないような作りか、使えるような作りかだと思うんだよね

408 :デフォルトの名無しさん:2008/08/31(日) 17:14:24
でもvectorだと生ポの6倍程度のメモリを使うんだぜ?

410 :デフォルトの名無しさん:2008/08/31(日) 17:43:56
>>408
6倍はないだろ。どんなコンパイラでどうやって測った?

411 :デフォルトの名無しさん:2008/08/31(日) 17:51:34
>>410
VC9でsizeof(std::vector<int>)で30が返ったんだが。
(20だったかも)

412 :デフォルトの名無しさん:2008/08/31(日) 17:57:02
>>411
10個突っ込んでも、300とか200にはならんと思うけど。
size() * sizeof(int) + Nbyteがせいぜいでない?

473 :デフォルトの名無しさん:2008/10/15(水) 21:25:20
デストラクタがvirtualじゃないvectorを継承すると
どういう落とし穴にはまるんですか?

477 :デフォルトの名無しさん:2008/10/16(木) 03:33:26
>>473-476
未定義動作。結果がどうなるか知りたければ試してみるしかないし、
やってみても何も起こらないかもしれないし、いつも同じ結果になるとも限らない。

575 :デフォルトの名無しさん:2009/04/02(木) 14:29:03
dequeってリニアアドレスじゃないけど、

dequer<MY_REC> items;
int i = items[index].MY_MEMBER;

って書けるんでしたっけ?

589 :デフォルトの名無しさん:2009/04/03(金) 17:06:03

vector<MY_REC> items;

で、
items.erase(&.items[1]);
とかしてたんだけど、

vectorをdequeにしたら、うわ、コンパイルエラー。

eraseの引数はイテレータンなんでつよね。
記述間違ってない希ガスるんだけど。

671 :デフォルトの名無しさん:2010/10/10(日) 20:47:27
STL固有の問題じゃないんだがこのコードが通らねぇ

std::set<void(Class::*)(int)> methods;
methods.insert(&Class::Method);

原因は、メンバー関数は==と!=以外の比較ができないから。
これ欠陥じゃね?

672 :デフォルトの名無しさん:2010/10/10(日) 20:58:39
>>671
メンバ関数へのポインタに限らず、普通関数へのポインタなんかコンテナに入れないだろ

673 :デフォルトの名無しさん:2010/10/10(日) 21:08:20
>>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に突っ込むなんてよくやりそうな事じゃ
ないか?

675 :デフォルトの名無しさん:2010/10/10(日) 21:21:17
>>673
お前はメンバ関数へのポインタを基礎からやり直せ

678 :デフォルトの名無しさん:2010/10/10(日) 21:30:17
>>675
 理屈は解ってんだよ。実行するまで本当の関数が特定できないから、
メンバー関数のポインターは普通のポインターじゃない。それは解ってる。
 しかし、一度なんらかの関数が代入が代入されると言うことは一意に関数を
識別できるってことではある。現に、関数ポインターを(long**)(&mp):として
とりだしてやれば一意の値を取り出すことも可能なんだ。だから、本来言語仕様で
制限するような事じゃないはずだろ。

718 :デフォルトの名無しさん:2011/01/10(月) 08:39:40
とはいっても、組込み屋としては例外吐かれても困る。
end() の参照を返すわけにもいくまい。
コンパイルエラーにしてくれる現状がベスト。

だいたいその程度なら自分でユーティリティ作ればいいだろう。


719 :デフォルトの名無しさん:2011/01/10(月) 08:44:34
>>718
組み込み屋はなんで例外吐かれると困るの?
どのみち map 使ってたら bad_alloc 飛んでくるんじゃね?

721 :デフォルトの名無しさん:2011/01/12(水) 14:28:35
>>719
処理速度やメモリ消費を考慮して例外を使用しない設定でビルドするよ。
STL コンテナを使うときには例外出さない自作アロケータ使うよ。


746 :デフォルトの名無しさん:2011/05/26(木) 18:50:01.19
v[i]=i を v.push_back(i) にかえる

747 :デフォルトの名無しさん:2011/05/26(木) 18:51:16.33
確かreserve()は領域を予約するだけで
アクセス可能になるわけではないと思いますが

748 :デフォルトの名無しさん:2011/05/26(木) 21:05:46.19
>>746

そうなんですが・・・ push_backでは時間がかかります。

>>747

実際、reserveしてみると、普通にV[i]=iのアクセスが可能です。

「いや、そう見えるだけであって実際には・・・の話かもしれないけど
(C++では意外なメカニズムに驚くことが多すぎて、自信ないです)。

749 :デフォルトの名無しさん:2011/05/26(木) 21:37:58.05
いや、そう見えるだけであって実際には範囲外アクセス

751 :デフォルトの名無しさん:2011/05/26(木) 21:58:20.92
>>748
あとreserveしたサイズ内でのpush_backならメモリの拡張処理は発生しないと
思うので、時間もかからないんじゃないの。
(どの環境なのか分からないので断言はできないが)

817 :デフォルトの名無しさん:2011/06/12(日) 21:08:13.91
mapってさ。iteratorがpair返すじゃん。
うんでさ、大抵のalgorithmってfirst、secondに引っかかるじゃん。
みんなどうしてんの?
わざわざpair用に噛ませるfunctorとか作ってんの?

818 :デフォルトの名無しさん:2011/06/12(日) 22:44:55.98
>>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;
}

843 :デフォルトの名無しさん:2011/07/03(日) 20:28:10.61
通報済み


http://hibari.2ch.net/test/read.cgi/tech/1104092624/l50人気ブログランキングへ