トップページ⇒tech
1001コメント341KB

●STL スレッド●

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
無いのが不思議
0002デフォルトの名無しさんNGNG
ここと同一人物か?
http://pc.2ch.net/test/read.cgi/tech/1004242305/
●とか使うなよバカ>1
0003デフォルトの名無しさんNGNG
>>1
そう思ってるなら、1に役立つリンクくらいはれよ…
0004デフォルトの名無しさんNGNG
まぁ、けっこう相談雑談に使えるんじゃないかなぁ。
俺は一応賛成しとく。
0005デフォルトの名無しさんNGNG
※STL=Stylish Temporary Language
まあ、Javascriptのような言語のことだけど、とくにスレをたてるほどのものではない。
0006デフォルトの名無しさんNGNG
STLなじまない。
0007デフォルトの名無しさんNGNG
>>5
素直にStandard Template Libraryについて話そうよ・・・
0008デフォルトの名無しさんNGNG
賛成です…
0009デフォルトの名無しさんNGNG
独自アロケータ使ってる人いますか?
0010デフォルトの名無しさんNGNG
VC++でのSTLバグとはどんなんでしょう。知っとかないと怖くて使えないよう。
0011デフォルトの名無しさんNGNG
>>9
STLと何の関係が・・・
0012デフォルトの名無しさんNGNG
>>11
関係無くはないと思うが・・・
0013デフォルトの名無しさんNGNG
>>11
template<class _Ty, class _A = allocator<_Ty> >
class vector {

これの第二引数を明示的に指定して使ってる人に、何か質問があるのでは?
私は使ったことないので知りませんが。
0014デフォルトの名無しさんNGNG
>>10
これ?
http://www.dinkumware.com/vc_fixes.html

あと VC6 は new が失敗したときに std::bad_alloc を投げずに 0
を返してくるのけど、STL はそれを意識したコードになっていないので、
メモリ保護違反が発生する可能性あり。_set_new_handler() で対処し
ましょう。

バグの件はさておくにしても VC 付属の STL には auto_ptr<>.reset()
がなかったりと仕様が古い部分があるので、私は STLport 入れて使って
ます。

http://www.stlport.org/
0015デフォルトの名無しさんNGNG
STLportだと、バグは解消って感じ?>>14
0016デフォルトの名無しさんNGNG
sgiのとどっちがいいの?
0017デフォルトの名無しさんNGNG
あのさあ、いちいちメモリ位置かわるのが、困るんだよね。
0018デフォルトの名無しさんNGNG
>>17
状況が良く分からんが、デザインパターン的には Iterator を作れ、というのが一般的な回答だと
思われ。
0019デフォルトの名無しさんNGNG
>>9
使ってるがコンテナも独自なんだなこれが・・
0020デフォルトの名無しさんNGNG
固定長の配列、reallocateのサポートとかやりたかったんだよ。
そしたらコンテナも独自にナチャタ(アヒャヒャヒャ
0021デフォルトの名無しさんNGNG
そいから operator new,delete のオーバーロードを有効化したアロケータとか
作ったな。やっぱり独自コンテナになっちまうが。(アヒャ
でも基本的なアルゴリズムだからやる事はほとんど決まってんだよね。
大して考える事ない。
0022デフォルトの名無しさんNGNG
>>15
とりあえず 14 のリンク先に上がってる程度のバグは残ってないです。

>>16
いまだと STLport の方がいいんじゃないかな。私もあまり細かく実装を追ってないんので技術的な
比較は出来ないんですが、STLport の方がこまめにリリースされていて、対応するプラットホームが
多いは確かです。

STLport は 4.0 のちょっと前から VC6 と組み合わせて使ってますが、今までで困ったのは

- ATL と組み合わせると min, max でコンパイルエラーが出る(ただし簡単に回避できるし、STLport 4.5
 では問題ない)
- OBSOLETE を定義しておかないと auto_ptr のコピーコンストラクタが使えない(VC6 のメンバテン
 プレートの仕様が古いから)

という程度。致命的な問題には、まだ出くわしてません。
0023デフォルトの名無しさんNGNG
>18
イテレータを保存しておけば、insertとかしたあといつでもそのベクトルの要素を指すことになるの?
0024デフォルトの名無しさんNGNG
>>22
4.5だとwindows.hとSTLPort、どっちのmin/maxが使用されるの?
0025STLPortよりNGNG
inline const _Tp& (max)(const _Tp& __a, const _Tp& __b)
(max)(size(), __n)
ナニやってんだろこれ・・
家に帰らないとわかんねーや。
0026デフォルトの名無しさんNGNG
STLPortをデバッグモードで使うとメモリリークが起きるんだけど(VC)。
これは俺の環境だけ?
002725NGNG
帰って実験した。
maxという名前のマクロ関数と
(max)という名前の関数が共存できてるみたい。
max(a, b); // これはマクロ関数
(max)(a, b); // これは関数
こんな構文ANSIにあったっけ?
002825NGNG
>>26
デバッグモードだからリークを通知してくれてるだけでは?
つまりリリースモードでも通知しないだけでリークしてる。
なんか開放し忘れてない?
0029名無しさん++NGNG
>>26
STLPort の iostream が static で確保しているオブジェクト(曜日のフォーマットとか)が、いくつか引っかかり
ますが、これは気にしなくても大丈夫です。

リークのチェックって、何を使ってます? _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF) を使っているなら
デバッガ出力に

> {43} normal block at 0x00343E30, 1328 bytes long.
> Data: <%a %b %e %H:%M:%> 25 61 20 25 62 20 25 65 20 25 48 3A 25 4D 3A 25

という感じで、最初に {数字} がありますよね。これを覚えておいて

1. CRT ソースの nh_malloc_dbg() にブレークポイントを設定
2. Alt + F9 でブレークポイント設定ダイアログを開く
3. 先ほど設定したブレークポイント選択して [条件] ボタンをクリック
4. スキップカウントに、デバッグ出力に出てきた数字 - 1 (上の例なら 42) を設定

でデバッガを走らせると、問題のメモリを確保しているときのスタックトレースが簡単に終えます。これで
問題があるかどうか判断して下さい。
0030デフォルトの名無しさんNGNG
アホか
0031デフォルトの名無しさんNGNG
>>27
構文でも何でもなく、Cの頃からあったマクロの回避方法だ。

max(x,y)で定義されたマクロは、
(max)(x,y)と書かれた部分に適用できない。
これはプリプロセッサの仕様だ。

で、コンパイラが
(max)(x,y)を見つけたとき、
()で囲った関数へのポインタ式 + ()で囲まれたコンマ区切りの式
->関数呼び出し
に展開する。

そんだけ
0032デフォルトの名無しさんNGNG
ユーザー側から呼ぶにも(max)(x,y)としないといけないの?
ダサすぎる・・・・・・・・・
003325NGNG
>>31
ありがとう!!
アホな俺に教えてくれて。
しかしプリプロセッサの仕様か。
可読性もイマイチだし、正直あまり使い所が見当たらないな・・。
0034デフォルトの名無しさんNGNG
>>29
念のため。realloc 入った瞬間に nh_malloc_dbg() 呼び出しとデバッガ出力の回数が一致しなくなるので、
WinMain 始まってからはカウントのとり方変えないとダメね。
0035デフォルトの名無しさんNGNG
マクロの副作用が欲しくないときは明示的に (max)(x,y)
テンプレート版や関数版使いたくて、そもそもそんなの気にしたくなければ
#undef max

好きにしろ屋ゴルァ
0036デフォルトの名無しさんNGNG
>>33
z = (((((max)))))(x,y);

とかすれば一目瞭然。
003726NGNG
>>28-29
ありがとうございます。
#define _STLP_DEBUG 1
をして、iostreamをincludeするだけで、
{66} normal block at 0x002F5588, 792 bytes long.
Data: <September > 53 65 70 74 65 6D 62 65 72 00 CD CD CD CD CD CD
こんなのが出力されるんで、内部に問題でもあるのかなと思ってましたが
気にしなくていいんですね。でもやっぱり気になる・・・
あと、デバッグの方法は勉強になります。
003825NGNG
>>36
うおーなんでこんなんでコンパイル通るんだYO!!
マクロは出来るだけ排除していこうと誓った2x才独身の夜。
0039デフォルトの名無しさんNGNG
STL便利なんだけど、
ローカルなクラスをテンプレートの引数にバインドできないんだけど(VC++)
C++の制限?
std::for_each とか、その場にファンクタ書けたら便利なのに。
0040コメント無しさんNGNG
>>39
ローカルなクラスってなによ?
0041名無しさん++NGNG
>>39
仕様です。

> 14.3.1 Template type arguments
>
> 2 A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall
> not be used as a templateargument for a template typeparameter.

テンプレートを展開する際にクラス名を単純に置換できなくなる(普通にスコープを切ると、テンプレート
側ではローカルクラスは見えない)のが問題なのだと推測されますが、できれば便利ですよね。

>>40
関数内で定義したクラスのことです。

int main(void)
{
  class foo {};  // これ
}
0042コメント無しさんNGNG
>>41
int main(void)
{
  class foo {};  // これ
}
とか
class foo
{
  class bar {};  // これ
};
とかって、正式名称なに?
0043名無しさん++NGNG
>>42
関数内で定義されたクラスは local class、クラス内で定義されたクラスは nested class です。
0044コメント無しさんNGNG
ありがとうございます。
あまりにもgoogleでひっかからないんで、ほかの名前があるかとオモタヨ
0045名無しさん++NGNG
>>44
C++ の規格書を手元に置いておくと宜しいかと。www.ansi.org から PDF 版を購入した場合 $18
です。

ISO/IEC 14882
Programming languages -- C++
http://webstore.ansi.org/ansidocstore/product.asp?sku=ISO%2FIEC+14882%2D1998
0046デフォルトの名無しさんNGNG
nested functionはないけれど
local classはあるのかー。
004739NGNG
>>41
ありがとうございます。
C++の仕様ですか。了解です。
std::for_each()、使いどころ難しいってことですね
(無理して使わなくてもいいんだけど)

私も >>45 の PDF 買っておこうかな・・・
0048デフォルトの名無しさんNGNG
STLの良い参考書って、どういうのがありますか?
0049揚げNGNG
良スレあげ
0050揚げNGNG
といいながら下げてしまった
おのれ くっきーめ
0051デフォルトの名無しさんNGNG
>>48
GenericProgramming
0052デフォルトの名無しさんNGNG
追加
http://www.ascii.co.jp/books/detail/4-7561/4-7561-3441-6.html
0053デフォルトの名無しさんNGNG
>>51 >>52
サンクス。読んでみるよ。
0054login:PenguinNGNG
>>38
#if, #ifdefで使う定数、call by nameが必要なもの、以外使わないのが吉。
0055デフォルトの名無しさんNGNG
>>29
でも、STL使ってると、うまくスキップしてくれないんだけど…
なんでなんだろ。
結局、あやしいところに
int* p = new int();
とかって、わざとリークさせて場所をしぼりこんだりしてる。

使い方が悪いのかな
0056名無しさん++NGNG
>>55
> でも、STL使ってると、うまくスキップしてくれないんだけど…
デバッグウィンドウに表示される数値とスキップ回数の対応がおかしい、という話ですか?

デバッグウィンドウに表示される回数は DBGHEAP.C で定義されている静的変数 _lRequestCurr
で管理されていますが、これは nh_malloc_dbg() だけではなく realloc_help() の中でもインクリメ
ントされます。したがって、こちらが呼ばれた場合にはスキップ回数と対応が取れなくなります。

場所を特定したいだけなら _CRTDBG_MAP_ALLOC を定義して <crtdbg.h> を読み込み、メモリ管
理関数を、行番号やファイル名情報を保存するデバッグ用関数にマッピングするのが簡単です。
それだけではなく、確実にブレークポイントを設定したいなら、少し面倒ですが次の手順を踏みま
す。

1 まず nh_malloc_dbg にブレークポイントを設定してデバッガを起動する。
2 ブレークポイントで停止したらクイックウォッチ (Shift + F9) ウィンドウを開き、_lRequestCurr
 変数のアドレスを調べる。(&_lRequestCurr と入力する)
3 いったんデバッガを終了する。
4 Alt + F9 でブレークポイント設定ダイアログを開き、データタブを選択。
5 評価される式の欄に *(long *)0x10205138 == 25 と入力。ただし 0x10205138 は 2 で調べた
 変数 _lRequestCurr のアドレス、25 はデバッガウィンドウにリークとして検出された番号 + 1。

で如何?
0057名無しさん++NGNG
>>55
念のため。

デバッグ版のライブラリ (stlport_vc6_stldebug.lib のようにライブラリ名に stldebug が含まれているもの)
をリンクしてますよね?
0058デフォルトの名無しさんNGNG
>>57
自動でリンクされるやん
0059デフォルトの名無しさんNGNG
>>58
条件による。VC6 だと /NODEFAULTLIB 指定すると #pragma comment(lib, xxx) 無視されるし。
0060デフォルトの名無しさんNGNG
とりあえずC++の話なんだけど、
std::listとstd::map を例外安全かつ中立な実装にできないかな?

型引数として渡されるクラスが例外安全・かつ中立であると
仮定しての話でよいです。

すでに、例外安全だったら素マン。出直してくる。
006155NGNG
>>56
ありがとう!できました。
別にアドレス調べなくても _lRequestCurr == (数字) で大丈夫だったよ。
スキップでやっちゃうと確かに数あってなかった。
ちなみに
_CRTDBG_MAP_ALLOC を定義すると new が
inline void* __cdecl operator new(unsigned int s)
{ return ::operator new(s, _NORMAL_BLOCK, __FILE__, __LINE__); }
って、なるんだが、DEBUG だとinline 展開できない(pdbが作成できない)
んで、__FILE__と__LINE__が意味なくなるんで、場所特定できないんです。

STL関係なし…
006260NGNG
とりあえず、該当部分はtry-catchをつかってexception safeにしといたよ。

でもだれか、知ってたら教えてちょんまげ。
0063デフォルトの名無しさんNGNG
漏れは知らないな。
STLは結構効率を気にしてそうだからな。
とりあえずthrowする部分を関数でラッピングしてみたりとか。
あるいはエラーの判断もassertみたいのでやって関数内部で例外
投げたり投げなかったりしてみたり。
006460NGNG
c++相談室3あたりで、しかも自分で解決してます。

複数要素の挿入以外は、きちっと例外安全と中立が
保証されてます。
すまんです、出直してきます。
0065デフォルトの名無しさんNGNG
導出したクラスで多種類のオブジェクトをコンテナに
入れるにはどうすればよいのでしょうか?
要するにこんなことがしたいのですが
class A { ... } ;
class B : public A { ... } ;

void func()
{
B b ;
vector< A > v ;
v.push_back( b ) ;
}
0066デフォルトの名無しさんNGNG
>>65
それコンパイルとおんないの?
0067デフォルトの名無しさんNGNG
>>66
コンパイルは通るけど、意図と違うと思う。

多態性はポインタで扱わないと使えません。>>65
0068デフォルトの名無しさんNGNG
ポインタって言うのはどうかな?
0069デフォルトの名無しさんNGNG
>>68
参照でも良いだろう、と?
0070デフォルトの名無しさんNGNG
 3つ以上の要素をSTLで扱う方法ってありませんか?
 具体的には、
struct A{
string name;
string tel;
string mail;
}
のように表されるデータのリストを、それぞれ(key、value1、value2)
をキーにしてソートしたいのです。
0071デフォルトの名無しさんNGNG
日本語で話せ、と。
0072デフォルトの名無しさんNGNG
具体的には〜ソートしたいのです。

なんか日本語が変だぞ
0073デフォルトの名無しさんNGNG
比較演算子をオーバーライドしなさい
0074デフォルトの名無しさんNGNG
日本語で話そー、と。
007570NGNG
 内容の不備より先に日本語の方を指摘されるとは……。
 出直して参ります。
0076デフォルトの名無しさんNGNG
>70
違うよ、出直すべきなのはここにいるプログラムヲタクだよ。
0077デフォルトの名無しさんNGNG
>>76
あんた何者?
0078デフォルトの名無しさんNGNG
仕様書もメールも、英数字は全部全角文字で書くタイプ。>>76
で、きっと、突っ込まれると全角文字ってなんだよって逆切れして
漢字コードの定義とインターネットで推奨されない文字コードの
フレームを作っちゃうタイプ。>>76
0079デフォルトの名無しさんNGNG
>78
おおー、ヲタクっぽい文章だこりゃ。きっと、パソコンの前にいるのはでかいブタだな。
0080名無しさん++NGNG
>>70
素直に map を 3 つ作るのはダメなんですか?

#include <algorithm>
#include <iostream>
#include <map>
#include <string>

struct A {
  std::string name;
  std::string tel;
  std::string mail;
  A(const char *name_, const char *tel_, const char *mail_)
    : name(name_), tel(tel_), mail(mail_)
  {}
};

std::ostream& operator<<(std::ostream& ostream, const struct A& a)
{
  ostream <<"name = " << a.name << ", tel = " << a.tel << ", mail = " << a.mail;
  return ostream;
}

struct Aprint {
  void operator()(const std::pair<std::string, struct A*>& pr)
  {
    std::cout << *pr.second << std::endl;
  }
};

// 続く
0081名無しさん++NGNG
>>80 の続き

int
main(void)
{
  struct A a[] = {
    A("zushi",  "11-1111-1111", "a@a"),
    A("abe",  "22-2222-2222", "b@b"),
    A("etou",  "00-0000-0000", "c@c"),
  };

  typedef std::map<std::string, struct A*> Amap_Type;
  Amap_Type amap_name, amap_tel, amap_mail;

  // map を作っとく
  for (size_t i = 0; i < sizeof(a) / sizeof(a[0]); ++i) {
    amap_name[a[i].name] = &a[i];
    amap_tel[a[i].tel] = &a[i];
    amap_mail[a[i].mail] = &a[i];
  }

  Amap_Type::iterator it;

  // sort by name
  std::cout << "-- sort by name -- " << std::endl;
  std::for_each(amap_name.begin(), amap_name.end(), Aprint());

  // sort by tel
  std::cout << "-- sort by tel -- " << std::endl;
  std::for_each(amap_tel.begin(), amap_tel.end(), Aprint());

  // sort by mail
  std::cout << "-- sort by mail -- " << std::endl;
  std::for_each(amap_mail.begin(), amap_mail.end(), Aprint());

  return (0);
}
0082デフォルトの名無しさんNGNG
>>80,81
どこが素直になのかイマイチわからん

>>70
素直に比較用の関数オブジェクト作って list の sort に渡せばいいんじゃないの
0083デフォルトの名無しさんNGNG
>>82
えーと、おれ70じゃないんだけど、こんな感じでいいんでしょか?

struct A { string name, tel, mail; ... };

struct sortbytel : public greater< A > {
 bool operator()(A& x, A& y) { return x.tel < y.tel; }
};

list< A > alist;
alist.sort(sortbytel());

VC5で試そうとしたら、list<T>::sortがヘタレで動作確認できませんでした。
(どんな比較関数渡してもgreaterが使われる)
008482NGNG
>>83
比較関数オブジェクトは greater から派生する必要ないです。

ただ、VCに付いてるSTLはヘタレなので通りません。
どっかから別のSTL持ってくるとか、
某land使うとか、gcc使うとかしてください。
0085名無しさん++NGNG
>>82
事前に sort 済みのデータを持っておくんじゃなくて、その場で sort したいって話なのか。
誤解してたよ。
0086デフォルトの名無しさんNGNG
話がずれるかもしれないが便乗。
STLには名前空間 stdがついていますか、
std::stringみたいに、いちいち指定していますか?

using namespace std; で済ましているのはダメ?
0087デフォルトの名無しさんNGNG
>>86
いちいち指定してられますか。
当然 using やってますよ。
影響が他に及ばないように、
自分のネームスペースの中でだけど。
008886NGNG
>>87
80さんがいちいち指定したもので、世の中そういうものなのかと。
良いか悪いかは別にしてね。
0089デフォルトの名無しさんNGNG
>>86
using std::string;
using std::vector;
using....
009070NGNG
 あう、24時間でレスがたくさん……
>>80,81(名無しさん++ さん)
 そう言えばそう言う手段もありましたね。
ただ、想定しているデータの量が8千件オーバーっぽい感じなので、
3倍メモリを食うのは辛いかも知れません。
 まあ、最近のPCですし、メモリもたかが知れてますが……

>>82 さん
 比較用の関数オブジェクト、ですか。助言ありがとうございます。
 初心者のくせに中途半端のままSTLの利用をはじめたという状態で、
手元にある参考書が(よりにもよってプログラマー板の必読書スレで
叩かれてる)標準C++:STLの基礎知識という本だけで、他に参考に
出来るものが無い状態……。
 これ、という参考書や参考になるHPなどはありませんでしょうか?
 自分なりに捜したつもりですが、関数オブジェクトの自作に関して
書かれているようなHPというのが見あたらない……。

 やっぱり勉強が足りないです。修行し直してきます。
0091名無しさん@EmacsNGNG
>>90=70
>>51 さんも言ってるけど漏れも
"Generic Programming -STLによる汎用プログラミング-"
はイイと思うぞ.
ASCII から出てて,4800円 + tax
ISBN4-7561-3441-6
009282NGNG
>>90
関数オブジェクトは、関数っぽく呼べるオブジェクトのことで、
要するに operator() を実装したクラスのこと。
本当は binary_function から派生するべきなんですが、
そんなことしなくても全然使えます。

83氏が書いてるよーな
struct sortbytel{
 bool operator()(const A& x, const A& y) { return x.tel < y.tel; }
};
ってヤツです(多少修正しました)。
inlineにするとスピードアップして幸せ。
009383NGNG
>>82
どもー。84で某ランド薦めてもらったので、BCC5.5.1を落としてみました。
92のコードもきっちりコンパイルできました。ああそれにしてもVCの馬鹿野郎!
というわけで、これでSTLの勉強が進められます。ありがとです。
0094デフォルトの名無しさんNGNG
僕もクラスのlistを、クラスのメンバ変数をキーとして
listをソートさせたいと考えています。(クラスStudentの
メンバ変数 string name; をキーにしてソートさせたい)

70の方とやりたいことは同じだと思うんですが・・
↑の方々の説明だけではまだ良く分かりません。
どのようにすればいいか教えてもらいたいんです。

>>82
>比較用の関数オブジェクト作って list の sort に渡せばいいんじゃないの
↑この部分をもう少し詳しく教えてほしいです。
お願いします。
0095デフォルトの名無しさんNGNG
ただ単にさ、std::set使えばいいんでないの?
operator=とoperator<実装するだけでいけるよ。
0096デフォルトの名無しさんNGNG
list<HOGE> hlist なら
static bool compareFunc(const HOGE &a, const HOGE &b) {
return a < b;
}
で、hlist.sort(compareFunc);
とか
class CompareClass {
public:
int _c;
CompareClass(int n) : _c(n) {}
bool operator()(const HOGE &a, const HOGE &b) {
++n;
return a < b;
}
};
で hlist.sort(CompareClass(0)); とか。
009796NGNG
あ、間違ってるし。ま、いいか
0098デフォルトの名無しさんNGNG
_で始まる名前を使うあたり、頭悪いと思うのはオレだけ?
0099デフォルトの名無しさんNGNG
自分と違うコーディング規約を指して頭悪いとかいうのは…
0100デフォルトの名無しさんNGNG
コーディング規約以前の問題ですよ。
0101デフォルトの名無しさんNGNG
>>96
++nは++_cですよね、そのカウンタ_cの最終値を取り出す方法が
わからないっす。どうやるんだろ…。
■ このスレッドは過去ログ倉庫に格納されています