5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

●STL スレッド●

1 :デフォルトの名無しさん:01/10/29 01:43
無いのが不思議

2 :デフォルトの名無しさん:01/10/29 01:45
ここと同一人物か?
http://pc.2ch.net/test/read.cgi/tech/1004242305/
●とか使うなよバカ>1

3 :デフォルトの名無しさん:01/10/29 01:46
>>1
そう思ってるなら、1に役立つリンクくらいはれよ…

4 :デフォルトの名無しさん:01/10/29 01:51
まぁ、けっこう相談雑談に使えるんじゃないかなぁ。
俺は一応賛成しとく。

5 :デフォルトの名無しさん:01/10/29 01:59
※STL=Stylish Temporary Language
まあ、Javascriptのような言語のことだけど、とくにスレをたてるほどのものではない。

6 :デフォルトの名無しさん:01/10/29 02:29
STLなじまない。

7 :デフォルトの名無しさん:01/10/29 04:49
>>5
素直にStandard Template Libraryについて話そうよ・・・

8 :デフォルトの名無しさん:01/10/29 04:53
賛成です…

9 :デフォルトの名無しさん:01/10/29 11:55
独自アロケータ使ってる人いますか?

10 :デフォルトの名無しさん:01/10/29 11:59
VC++でのSTLバグとはどんなんでしょう。知っとかないと怖くて使えないよう。

11 :デフォルトの名無しさん:01/10/29 11:59
>>9
STLと何の関係が・・・

12 :デフォルトの名無しさん:01/10/29 12:29
>>11
関係無くはないと思うが・・・

13 :デフォルトの名無しさん:01/10/29 12:31
>>11
template<class _Ty, class _A = allocator<_Ty> >
class vector {

これの第二引数を明示的に指定して使ってる人に、何か質問があるのでは?
私は使ったことないので知りませんが。

14 :デフォルトの名無しさん:01/10/29 12:37
>>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/

15 :デフォルトの名無しさん:01/10/29 12:46
STLportだと、バグは解消って感じ?>>14

16 :デフォルトの名無しさん:01/10/29 13:37
sgiのとどっちがいいの?

17 :デフォルトの名無しさん:01/10/29 13:52
あのさあ、いちいちメモリ位置かわるのが、困るんだよね。

18 :デフォルトの名無しさん:01/10/29 14:56
>>17
状況が良く分からんが、デザインパターン的には Iterator を作れ、というのが一般的な回答だと
思われ。

19 :デフォルトの名無しさん:01/10/29 15:11
>>9
使ってるがコンテナも独自なんだなこれが・・

20 :デフォルトの名無しさん:01/10/29 15:13
固定長の配列、reallocateのサポートとかやりたかったんだよ。
そしたらコンテナも独自にナチャタ(アヒャヒャヒャ

21 :デフォルトの名無しさん:01/10/29 15:18
そいから operator new,delete のオーバーロードを有効化したアロケータとか
作ったな。やっぱり独自コンテナになっちまうが。(アヒャ
でも基本的なアルゴリズムだからやる事はほとんど決まってんだよね。
大して考える事ない。

22 :デフォルトの名無しさん:01/10/29 15:29
>>15
とりあえず 14 のリンク先に上がってる程度のバグは残ってないです。

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

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

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

という程度。致命的な問題には、まだ出くわしてません。

23 :デフォルトの名無しさん:01/10/29 16:06
>18
イテレータを保存しておけば、insertとかしたあといつでもそのベクトルの要素を指すことになるの?

24 :デフォルトの名無しさん:01/10/29 16:10
>>22
4.5だとwindows.hとSTLPort、どっちのmin/maxが使用されるの?

25 :STLPortより:01/10/29 16:17
inline const _Tp& (max)(const _Tp& __a, const _Tp& __b)
(max)(size(), __n)
ナニやってんだろこれ・・
家に帰らないとわかんねーや。

26 :デフォルトの名無しさん:01/10/30 00:03
STLPortをデバッグモードで使うとメモリリークが起きるんだけど(VC)。
これは俺の環境だけ?

27 :25:01/10/30 00:29
帰って実験した。
maxという名前のマクロ関数と
(max)という名前の関数が共存できてるみたい。
max(a, b); // これはマクロ関数
(max)(a, b); // これは関数
こんな構文ANSIにあったっけ?

28 :25:01/10/30 00:32
>>26
デバッグモードだからリークを通知してくれてるだけでは?
つまりリリースモードでも通知しないだけでリークしてる。
なんか開放し忘れてない?

29 :名無しさん++:01/10/30 00:33
>>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) を設定

でデバッガを走らせると、問題のメモリを確保しているときのスタックトレースが簡単に終えます。これで
問題があるかどうか判断して下さい。

30 :デフォルトの名無しさん:01/10/30 00:35
アホか

31 :デフォルトの名無しさん:01/10/30 00:37
>>27
構文でも何でもなく、Cの頃からあったマクロの回避方法だ。

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

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

そんだけ

32 :デフォルトの名無しさん:01/10/30 00:40
ユーザー側から呼ぶにも(max)(x,y)としないといけないの?
ダサすぎる・・・・・・・・・

33 :25:01/10/30 00:42
>>31
ありがとう!!
アホな俺に教えてくれて。
しかしプリプロセッサの仕様か。
可読性もイマイチだし、正直あまり使い所が見当たらないな・・。

34 :デフォルトの名無しさん:01/10/30 00:49
>>29
念のため。realloc 入った瞬間に nh_malloc_dbg() 呼び出しとデバッガ出力の回数が一致しなくなるので、
WinMain 始まってからはカウントのとり方変えないとダメね。

35 :デフォルトの名無しさん:01/10/30 00:52
マクロの副作用が欲しくないときは明示的に (max)(x,y)
テンプレート版や関数版使いたくて、そもそもそんなの気にしたくなければ
#undef max

好きにしろ屋ゴルァ

36 :デフォルトの名無しさん:01/10/30 00:54
>>33
z = (((((max)))))(x,y);

とかすれば一目瞭然。

37 :26:01/10/30 00:56
>>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
こんなのが出力されるんで、内部に問題でもあるのかなと思ってましたが
気にしなくていいんですね。でもやっぱり気になる・・・
あと、デバッグの方法は勉強になります。

38 :25:01/10/30 01:08
>>36
うおーなんでこんなんでコンパイル通るんだYO!!
マクロは出来るだけ排除していこうと誓った2x才独身の夜。

39 :デフォルトの名無しさん:01/10/30 03:08
STL便利なんだけど、
ローカルなクラスをテンプレートの引数にバインドできないんだけど(VC++)
C++の制限?
std::for_each とか、その場にファンクタ書けたら便利なのに。

40 :コメント無しさん:01/10/30 03:34
>>39
ローカルなクラスってなによ?

41 :名無しさん++:01/10/30 03:47
>>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 {};  // これ
}

42 :コメント無しさん:01/10/30 03:58
>>41
int main(void)
{
  class foo {};  // これ
}
とか
class foo
{
  class bar {};  // これ
};
とかって、正式名称なに?

43 :名無しさん++:01/10/30 04:06
>>42
関数内で定義されたクラスは local class、クラス内で定義されたクラスは nested class です。

44 :コメント無しさん:01/10/30 04:10
ありがとうございます。
あまりにもgoogleでひっかからないんで、ほかの名前があるかとオモタヨ

45 :名無しさん++:01/10/30 08:08
>>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

46 :デフォルトの名無しさん:01/10/30 08:42
nested functionはないけれど
local classはあるのかー。

47 :39:01/10/31 03:35
>>41
ありがとうございます。
C++の仕様ですか。了解です。
std::for_each()、使いどころ難しいってことですね
(無理して使わなくてもいいんだけど)

私も >>45 の PDF 買っておこうかな・・・

48 :デフォルトの名無しさん:01/10/31 14:02
STLの良い参考書って、どういうのがありますか?

49 :揚げ:01/10/31 17:19
良スレあげ

50 :揚げ:01/10/31 17:20
といいながら下げてしまった
おのれ くっきーめ

51 :デフォルトの名無しさん:01/11/01 18:56
>>48
GenericProgramming

52 :デフォルトの名無しさん:01/11/01 19:11
追加
http://www.ascii.co.jp/books/detail/4-7561/4-7561-3441-6.html

53 :デフォルトの名無しさん:01/11/02 14:20
>>51 >>52
サンクス。読んでみるよ。

54 :login:Penguin:01/11/03 09:12
>>38
#if, #ifdefで使う定数、call by nameが必要なもの、以外使わないのが吉。

55 :デフォルトの名無しさん:01/11/03 14:11
>>29
でも、STL使ってると、うまくスキップしてくれないんだけど…
なんでなんだろ。
結局、あやしいところに
int* p = new int();
とかって、わざとリークさせて場所をしぼりこんだりしてる。

使い方が悪いのかな

56 :名無しさん++:01/11/03 14:53
>>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。

で如何?

57 :名無しさん++:01/11/03 15:16
>>55
念のため。

デバッグ版のライブラリ (stlport_vc6_stldebug.lib のようにライブラリ名に stldebug が含まれているもの)
をリンクしてますよね?

58 :デフォルトの名無しさん:01/11/03 15:34
>>57
自動でリンクされるやん

59 :デフォルトの名無しさん:01/11/03 15:45
>>58
条件による。VC6 だと /NODEFAULTLIB 指定すると #pragma comment(lib, xxx) 無視されるし。

60 :デフォルトの名無しさん:01/11/03 16:50
とりあえずC++の話なんだけど、
std::listとstd::map を例外安全かつ中立な実装にできないかな?

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

すでに、例外安全だったら素マン。出直してくる。

61 :55:01/11/04 01:14
>>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関係なし…

62 :60:01/11/05 23:12
とりあえず、該当部分はtry-catchをつかってexception safeにしといたよ。

でもだれか、知ってたら教えてちょんまげ。

63 :デフォルトの名無しさん:01/11/06 23:59
漏れは知らないな。
STLは結構効率を気にしてそうだからな。
とりあえずthrowする部分を関数でラッピングしてみたりとか。
あるいはエラーの判断もassertみたいのでやって関数内部で例外
投げたり投げなかったりしてみたり。

64 :60:01/11/07 00:11
c++相談室3あたりで、しかも自分で解決してます。

複数要素の挿入以外は、きちっと例外安全と中立が
保証されてます。
すまんです、出直してきます。

65 :デフォルトの名無しさん:01/11/08 07:54
導出したクラスで多種類のオブジェクトをコンテナに
入れるにはどうすればよいのでしょうか?
要するにこんなことがしたいのですが
class A { ... } ;
class B : public A { ... } ;

void func()
{
B b ;
vector< A > v ;
v.push_back( b ) ;
}

66 :デフォルトの名無しさん:01/11/08 09:00
>>65
それコンパイルとおんないの?

67 :デフォルトの名無しさん:01/11/08 10:38
>>66
コンパイルは通るけど、意図と違うと思う。

多態性はポインタで扱わないと使えません。>>65

68 :デフォルトの名無しさん:01/11/08 22:29
ポインタって言うのはどうかな?

69 :デフォルトの名無しさん:01/11/08 23:19
>>68
参照でも良いだろう、と?

70 :デフォルトの名無しさん:01/11/08 23:47
 3つ以上の要素をSTLで扱う方法ってありませんか?
 具体的には、
struct A{
string name;
string tel;
string mail;
}
のように表されるデータのリストを、それぞれ(key、value1、value2)
をキーにしてソートしたいのです。

71 :デフォルトの名無しさん:01/11/08 23:47
日本語で話せ、と。

72 :デフォルトの名無しさん:01/11/08 23:54
具体的には〜ソートしたいのです。

なんか日本語が変だぞ

73 :デフォルトの名無しさん:01/11/09 00:00
比較演算子をオーバーライドしなさい

74 :デフォルトの名無しさん:01/11/09 00:01
日本語で話そー、と。

75 :70:01/11/09 00:11
 内容の不備より先に日本語の方を指摘されるとは……。
 出直して参ります。

76 :デフォルトの名無しさん:01/11/09 00:13
>70
違うよ、出直すべきなのはここにいるプログラムヲタクだよ。

77 :デフォルトの名無しさん:01/11/09 00:25
>>76
あんた何者?

78 :デフォルトの名無しさん:01/11/09 00:31
仕様書もメールも、英数字は全部全角文字で書くタイプ。>>76
で、きっと、突っ込まれると全角文字ってなんだよって逆切れして
漢字コードの定義とインターネットで推奨されない文字コードの
フレームを作っちゃうタイプ。>>76

79 :デフォルトの名無しさん:01/11/09 00:35
>78
おおー、ヲタクっぽい文章だこりゃ。きっと、パソコンの前にいるのはでかいブタだな。

80 :名無しさん++:01/11/09 00:52
>>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;
  }
};

// 続く

81 :名無しさん++:01/11/09 00:52
>>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);
}

82 :デフォルトの名無しさん:01/11/09 11:41
>>80,81
どこが素直になのかイマイチわからん

>>70
素直に比較用の関数オブジェクト作って list の sort に渡せばいいんじゃないの

83 :デフォルトの名無しさん:01/11/09 15:28
>>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が使われる)

84 :82:01/11/09 17:20
>>83
比較関数オブジェクトは greater から派生する必要ないです。

ただ、VCに付いてるSTLはヘタレなので通りません。
どっかから別のSTL持ってくるとか、
某land使うとか、gcc使うとかしてください。

85 :名無しさん++:01/11/09 23:12
>>82
事前に sort 済みのデータを持っておくんじゃなくて、その場で sort したいって話なのか。
誤解してたよ。

86 :デフォルトの名無しさん:01/11/10 00:12
話がずれるかもしれないが便乗。
STLには名前空間 stdがついていますか、
std::stringみたいに、いちいち指定していますか?

using namespace std; で済ましているのはダメ?

87 :デフォルトの名無しさん:01/11/10 00:15
>>86
いちいち指定してられますか。
当然 using やってますよ。
影響が他に及ばないように、
自分のネームスペースの中でだけど。

88 :86:01/11/10 00:24
>>87
80さんがいちいち指定したもので、世の中そういうものなのかと。
良いか悪いかは別にしてね。

89 :デフォルトの名無しさん:01/11/10 00:38
>>86
using std::string;
using std::vector;
using....

90 :70:01/11/10 01:23
 あう、24時間でレスがたくさん……
>>80,81(名無しさん++ さん)
 そう言えばそう言う手段もありましたね。
ただ、想定しているデータの量が8千件オーバーっぽい感じなので、
3倍メモリを食うのは辛いかも知れません。
 まあ、最近のPCですし、メモリもたかが知れてますが……

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

 やっぱり勉強が足りないです。修行し直してきます。

91 :名無しさん@Emacs:01/11/10 01:48
>>90=70
>>51 さんも言ってるけど漏れも
"Generic Programming -STLによる汎用プログラミング-"
はイイと思うぞ.
ASCII から出てて,4800円 + tax
ISBN4-7561-3441-6

92 :82:01/11/10 02:26
>>90
関数オブジェクトは、関数っぽく呼べるオブジェクトのことで、
要するに operator() を実装したクラスのこと。
本当は binary_function から派生するべきなんですが、
そんなことしなくても全然使えます。

83氏が書いてるよーな
struct sortbytel{
 bool operator()(const A& x, const A& y) { return x.tel < y.tel; }
};
ってヤツです(多少修正しました)。
inlineにするとスピードアップして幸せ。

93 :83:01/11/10 03:48
>>82
どもー。84で某ランド薦めてもらったので、BCC5.5.1を落としてみました。
92のコードもきっちりコンパイルできました。ああそれにしてもVCの馬鹿野郎!
というわけで、これでSTLの勉強が進められます。ありがとです。

94 :デフォルトの名無しさん:01/11/11 00:00
僕もクラスのlistを、クラスのメンバ変数をキーとして
listをソートさせたいと考えています。(クラスStudentの
メンバ変数 string name; をキーにしてソートさせたい)

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

>>82
>比較用の関数オブジェクト作って list の sort に渡せばいいんじゃないの
↑この部分をもう少し詳しく教えてほしいです。
お願いします。

95 :デフォルトの名無しさん:01/11/11 00:08
ただ単にさ、std::set使えばいいんでないの?
operator=とoperator<実装するだけでいけるよ。

96 :デフォルトの名無しさん:01/11/11 00:11
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)); とか。

97 :96:01/11/11 00:13
あ、間違ってるし。ま、いいか

98 :デフォルトの名無しさん:01/11/11 00:18
_で始まる名前を使うあたり、頭悪いと思うのはオレだけ?

99 :デフォルトの名無しさん:01/11/11 00:23
自分と違うコーディング規約を指して頭悪いとかいうのは…

100 :デフォルトの名無しさん:01/11/11 00:25
コーディング規約以前の問題ですよ。

101 :デフォルトの名無しさん:01/11/11 00:28
>>96
++nは++_cですよね、そのカウンタ_cの最終値を取り出す方法が
わからないっす。どうやるんだろ…。

102 :デフォルトの名無しさん:01/11/11 00:28
>>99>>100
`__`と`_`+英大文字で始まるのは予約語。
_+英小文字は「だめ」とは明文化されていません。

103 :デフォルトの名無しさん:01/11/11 00:28
_か__で始まる名前は使っちゃいかんですよ

104 :デフォルトの名無しさん:01/11/11 00:34
堂々とそういう名前使ってる本多いよね。
armやk&r読まないのって、やっぱ、罪だよな。

105 :101:01/11/11 01:00
>>101 わかった。
カウンタはstaticにするのね。

106 :96:01/11/11 01:12
>>105
関数ポインタも渡せる以上関数オブジェクトを
値コピーでなく参照渡しにすることはでけんのかな
つーことで、今試してみたけどstaticにするとか
自オブジェクトの外の何かを更新するとかしかなさそう

107 :105:01/11/11 01:30
>>106
ども。あれからドキュメントひっくり返して見てたら、
for_eachなんかは第3引数の関数オブジェクトがそのままfor_eachの戻り値になるから
staticじゃないメンバも取得できるんですね。STLっておもしれー。

108 :デフォルトの名無しさん:01/11/11 01:36
それしらんかった。
後で試してみよう

109 :デフォルトの名無しさん:01/11/11 01:44
listのソートは控えめに言っても時間がかかるから、
各要素へのポインタを持つ配列を一時的に作ってやった方が
何倍も速いよ。特に何度もソートする場合は。

110 :デフォルトの名無しさん:01/11/11 01:48
だからsetかmultisetつかえって!

111 :デフォルトの名無しさん:01/11/11 01:54
そだね。setが常套手段。
なんでlistにこだわってるのかわからないね。

112 :デフォルトの名無しさん:01/11/11 01:56
挿入にかかる時間が、setより小さいよね。

113 :デフォルトの名無しさん:01/11/11 02:03
挿入なんて話出てたっけ?

114 :デフォルトの名無しさん:01/11/11 03:35
でてないけど、他にlistにこだわる理由が思いつかないからねー

115 :94 :01/11/11 03:47
みなさん、ご親切にありがとうございます。
listにこだわっているのは"sort"するよりも
list内を順次辿る処理が多いからです。"sort"は
常にするのでなく必要な時に行う処理としています。

質問の具体例に出したクラスがまずかったです。
シンプルに例をあげようと思いまして。。

でもlistをsetに乗り換えてもいいのかなとも思えてきました。
ソートしながら追加してくれて便利だし,それほど処理時間に
大差が無いのであれば・・

116 :94:01/11/11 04:00
http://www.d1.dion.ne.jp/~ecb/cpp/07_15_02.html

↑にちょうどいいサンプルがありました。皆さんのご助言と
このサンプルを見ると、setでoperator"<"を使うと自動的に
キーを参照してソートしてくれることまでは分かりました。

ただ、なぜoperator"<"を使うとそのような処理ができる
のかが分かりません。このoperator"<"は
>>96さんが例示してくれたサンプルのCompareFuncとも
似ているようですが・・

↑のページのサンプルを参考にして,

Class HOGE に
string name;
というメンバ変数があったとして

list<HOGE> hlist;
bool compareFunc(const HOGE &a) const{
return name < a.name;
}

hlist.sort(compareFunc);

とすればClass Hogeの要素はnameをキーにして
アルファベット順に追加されるようになるんでしょうか?

基礎的な部分っぽいですが、教えて下さい。
お願いします。

117 :94:01/11/11 04:03
すみません。間違えました。

>...とすればClass Hogeの要素はnameをキーにして
>アルファベット順に追加されるようになるんでしょうか?

 ...とすればClass Hogeの要素はnameをキーにして
 "アルファベット順にソートされるんでしょうか?”

 の間違いです。すみません。

118 :デフォルトの名無しさん:01/11/11 04:04
bool operator < (const HOGE &a, const HOGE &b)
を作っておけばよい。

119 :94 :01/11/11 07:38
>>118
 しつこくてすみません。
 もう少し詳しく教えて下さい。

120 :デフォルトの名無しさん:01/11/11 13:27
>>119
#include <algorithm>
#include <iostream>
#include <list>
#include <string>

std::ostream& operator<<(std::ostream& ostream, const struct A& a);

struct A {
  std::string name;
  std::string tel;
  std::string mail;

  A(const std::string& name_, const std::string& tel_, const std::string& mail_)
    : name(name_), tel(tel_), mail(mail_)
  {}

  struct Sort {
    struct ByName {
      inline bool operator()(const A& a1, const A& a2)
      {
        return a1.name < a2.name;
      }
    };
    struct ByTel {
      inline bool operator()(const A& a1, const A& a2)
      {
        return a1.tel < a2.tel;
      }
    };
    struct ByMail {
      inline bool operator()(const A& a1, const A& a2)
      {
        return a1.mail < a2.mail;
      }
    };
  };

  class PrintLn {
    std::ostream& ostr;
  public:
    PrintLn(std::ostream& ostr_ = std::cout)
      : ostr(ostr_)
    {}
    inline void operator()(const A& a)
    {
      ostr << a << std::endl;
    }
  };
};

121 :デフォルトの名無しさん:01/11/11 13:27
>>120 続き
std::ostream& operator<<(std::ostream& ostr, const struct A& a)
{
  ostr << "name = " << a.name << ", tel = " << a.tel << ", mail = " << a.mail;
  return ostr;
}

int
main(void)
{
  std::list<A> list;
  list.push_back(A("zushi", "11-1111-1111", "a@a"));
  list.push_back(A("abe", "22-2222-2222", "b@b"));
  list.push_back(A("etou", "00-0000-0000", "c@c"));

  std::cout << "-- sort by name -- " << std::endl;
  list.sort(A::Sort::ByName());
  std::for_each(list.begin(), list.end(), A::PrintLn());

  std::cout << "-- sort by tel -- " << std::endl;
  list.sort(A::Sort::ByTel());
  std::for_each(list.begin(), list.end(), A::PrintLn());

  std::cout << "-- sort by mail -- " << std::endl;
  list.sort(A::Sort::ByMail());
  std::for_each(list.begin(), list.end(), A::PrintLn());

  return (0);
}

122 :70:01/11/11 19:16
>>91 さん
 4800円……
 金貯めるところからはじめます(涙

123 :94 :01/11/12 02:07
>120,121さん
 ご親切にどうも。ほんと勉強になります。

124 :70:01/11/12 23:27
>>120,121 さん
 ちょうど私のやりたかったのもそのような感じでした。
 説明ヘタすぎ……鬱。
 このソースでビルドしようとしたところ、「ist.sort(A::Sort::ByName())」の
部分でエラーが出ました。これが>>82 さんの言うVC6のだめな部分なのでしょうか?
 私のところでは利用するPCの都合でBCCを入れたりSTLPortを入れたりが出来ないのですが、
VC6で同様の処理をしようとした場合、どのようにすればいいでしょうか?

125 :デフォルトの名無しさん:01/11/13 00:54
>>124
・・・。
list をやめて vector か deque にする。

126 :デフォルトの名無しさん:01/11/13 01:06
だからsetかmultiset使えって!

127 :70:01/11/13 23:09
>>125,126 さん
 そうでした……なんでlistにこだわってたんだろう……逝ってきます。

128 :94:01/11/14 01:34
わーい。"list"でソート実装できました(^∀^)!
皆さん,本当にありがとうございました!

129 :デフォルトの名無しさん:01/11/20 00:19
VC6使ってるなら、単純にlistのメンバ演算子をオーバーロードすりゃソートなんて簡単にできるんだがなぁ。

130 :デフォルトの名無しさん:01/11/21 20:20
>>129
そうなん? サンプルコードあったら、Copy & Paste かリンクを希望。

131 :デフォルトの名無しさん:01/11/22 13:24
>>129
期待age

132 :デフォルトの名無しさん:01/11/22 19:38
STLが好かん場合、どうすればいいでしょか。

133 :デフォルトの名無しさん:01/11/22 20:20
車輪を再発明しなさい

134 :デフォルトの名無しさん:01/11/22 21:49
listに使える 3(+1)つの sort
http://www.s34.co.jp/cpptechdoc/article/sort/index.html

なんてのはどうなんでしょう

135 :デフォルトの名無しさん:01/11/22 22:23
>>132
転職すれば?

136 :デフォルトの名無しさん:01/11/24 22:04
age

137 :デフォルトの名無しさん:01/11/24 22:54
RubyとC++&STLは、速度は後者圧倒的有利だが、生産性と保守性はどうだろうか?
絶対的解は有りえないが御意見頂戴。

138 :デフォルトの名無しさん:01/11/24 23:05
ここでRubyと書いてもつまらんので、STLと書いてみる。
コンパイル時に解決される項目の多いSTLの方がラク。
苦しいたとえだが、
DLLよりスタッティックリンクがトラブル少な目なように。

139 :デフォルトの名無しさん:01/11/24 23:27
RubyがC++&STLでできているのに何を言う

140 :デフォルトの名無しさん:01/11/24 23:34
>>137
インターフェースに対してプログラミングするオブジェクト指向プログラミングのパラダイムと、
型をパラメタ化する Generic Programming は、対立するよりも相互補完する関係にあると思
うが。

141 :デフォルトの名無しさん:01/11/24 23:35
RubyはPerlでできています。

142 :デフォルトの名無しさん:01/11/25 01:48
Rubyの半分は優しさでできてます。

143 :デフォルトの名無しさん:01/11/25 02:04
>142
あとの半分は、行き場と根拠と品性のないプライドか何かですか?

144 :デフォルトの名無しさん:01/11/26 00:45
ワラタ

145 :デフォルトの名無しさん:01/11/26 03:12
どうしてRubyが話題に挙がるとすぐに荒れるんだろうか?

146 :デフォルトの名無しさん:01/11/26 04:18
>>145
Rubyまんせー係の人と、Rubyは糞係の人(合わせて一人以上)がいるから。
暇になると適当な言語のスレにどっちかを書いて撒餌。
厨房が寄ってきてどうでもいいことを書き散らす。
たちが悪いのはスレ住人が無視しても自作自演で続けること。
VB、HSP、Delphi、Ruby などある程度のユーザがいるが
簡易言語系、マイナー系に属する言語が対象となる。

書き込みの特徴
・○○ (言語名だけ連呼)
・○○>>>>○○ (根拠のない比較)
・○○は○○でできている
・○○は実用性がない/将来性がない/遅い (理由を示さず)
・○○を使っているやつは糞
・○○があるから必要がない

147 :デフォルトの名無しさん:01/11/27 11:43
>146
全部やった事あるある。ヒッキーだから暇ある。鬱ある。

148 :デフォルトの名無しさん:01/11/28 01:23
VC6 + STLport でリークが検出される話だけど、STLport が使ってる node allocator が原因かも
しれず。(__node_alloc は malloc/new してきたチャンクを、必ずしも返してない)

#define _STLP_USE_MALLOC

これで node allocator を使わずに全部 malloc 使って確保するようになるけど、どう?

149 :デフォルトの名無しさん:01/11/28 01:33
age

150 :デフォルトの名無しさん:01/11/28 05:10

http://news.2ch.net/test/read.cgi/news/1006626445/

151 :デフォルトの名無しさん:01/11/29 01:22
STLにはただの二分木はないみたいなんですが、純粋な二分木を
使うときはみなさんどうしますか? 勝手に平衡にされると困って
しまうんです。レイトレーシングの光の追跡に使うんですが・・・。

152 :デフォルトの名無しさん:01/11/29 01:42
BSP?そーゆーのだったら自作したほうが良い木がするなー。

153 :デフォルトの名無しさん:01/11/29 01:45
>>151
どの部分に使うの?シーングラフじゃないよな
カメラからの場所の切り分けか?それならBSPを実装するのがよろし

STL関係は便利な反面new deleteとかソートとかサーチが入るコンテナが
多いからレイトレみたいなプリミティブな実装で済むandタイトな場合は自分で
実装したほうが良いと思うぞ

あんまりSTLと関係ないな sage

154 :デフォルトの名無しさん:01/11/29 01:46
かぶった・・・ウツダ

でも同じ考えの人がいてくれてチョトうれしい(w

155 :151:01/11/29 02:39
光が反射したり屈折したりしていきますよね?
その構造を二分木で保存したいのです。
やっぱ自分で実装ですかね・・・。

156 :デフォルトの名無しさん:01/11/29 03:02
>>155
なるほど。ちょっと脱線だけれど、
木構築してどうするの?
最後にその木を使って追っていくってことかな?
再帰のほうが楽そうだけれど。

で、そのbinary treeだったら自作してもほとんど苦労しないような気がしますが・・・?

157 :151:01/11/29 03:30
そうです。追っていくんです。
考えてみたら再帰で充分ですね・・・。

自作はやっぱりテストまで含めると若干面倒なのと、
みなさんどうしてるのかな、ってことが気になったもので。

キューやスタックなどの単純なコンテナがあるのに、
二分木がないのも不思議だったんです。

158 :デフォルトの名無しさん:01/11/29 06:49
「スタック」「キュー」と「二分木」は視点が違いますよ

159 :151:01/11/30 01:18
>>158

よろしければ、その違いを説明してくれませんか?

ぼくとしては、TC4のコンテナクラスにはただのバイナリツリーはあったし、
データ構造としてキューもスタックも二分木も並列関係にあると思って
いるんですが・・・。

160 :デフォルトの名無しさん:01/11/30 01:31
>>159
158 じゃないけど、純粋な B-Tree を必要とする用途は限られているから、敢えて標準
ライブラリには入れなかっただけじゃないかな。

#あまり技術的な話じゃないんで sage

161 :デフォルトの名無しさん:01/11/30 01:43
SGI/HP STLとかSTLportなら内部的にtree持ってるから
それを使ってみるというのはどうか

162 :デフォルトの名無しさん:01/11/30 01:50
>>160
B-Treeとバイナリツリーは別物ですよ。
私も昔間違えましたが・・・。

163 :デフォルトの名無しさん:01/11/30 01:52
>>159 >>160
158じゃないけど、>>160 というよりも、
意味が違うという感じ。
「スタック」「キュー」は「用途」「インターフェイス」であってユーザの関心事だけど、
「二分木」「赤黒木」というのは「実装」であってユーザの
関心事でないということ、だと思う。つまり、set/mapが何を使って実装されているかは
問題でない、ということではないかな。

164 :デフォルトの名無しさん:01/11/30 02:15
>>162
検索してみたら B木というと、各ノードが保持するキーと子供の数が可変なのね。なるほど。
(いままで Binary Tree の略かと思ってたよ)

165 :デフォルトの名無しさん:01/11/30 07:36
Binary-Tree と B-Tree は違うものらしい。B の語源は非常に謎。

166 :デフォルトの名無しさん:01/11/30 09:33
>>165
考案者は Bayer というから、それと関係するかも。

167 :デフォルトの名無しさん:01/11/30 10:17
・・・人名なのか?

168 :デフォルトの名無しさん:01/11/30 10:42
B-treeの考案者はBayerとMcCreightという人らしい

169 :151:01/11/30 23:15
みなさんありがとうございました。
確かに、純粋な二分木を必要とする事って現実的には
あまりないかもしれませんね。

ただ、実装も大した手間じゃないだろうし、あって損は
ないのにな、という感は拭えませんが。

170 :デフォルトの名無しさん:01/11/30 23:33
>>169
作ったら、ベクターあたりで公開すると他の人が ウマー かも。

171 :デフォルトの名無しさん:01/11/30 23:33
大した手間じゃなかったら、それこそ自分でやればいいじゃん。

172 :デフォルトの名無しさん:01/11/30 23:35
basic_string には、data() と c_str()、length() と size() という
同じ動作(と思う)のメンバ関数がありますけど、
どっちかが非推奨だったりするんでしょうか?

173 :158:01/11/30 23:37
>>169
今更ですが、自分は>>163に書いてあるようなことのつもりで書きました。
「二分木」を使って実装された「スタック」とかいうのもありえるわけです。
(STLでそういう実装をしてるところはないはずですが)

174 :デフォルトの名無しさん:01/11/30 23:52
>>172
length()とsize()は一緒だが、data()とc_str()は別だぞ。
c_str()は末尾に'\0'が付加されるがdata()だと付かない。
length()に関しては文字列に長さがないのも変だろうって
程度の理由だったと思った。

175 :デフォルトの名無しさん:01/12/01 00:00
>>172
c_str() は '\0' つきの文字列を返すのに対して、data() は '\0' がついていない配列を
返す(正確には size() バイト分のデータしか保証されないので、その後に '\0' がくる
ことは保証されない)という違いがある。

#たいていの実装では c_str() も data() も '\0' つきの配列を返してくるけど。

176 :172:01/12/01 00:11
>>174-175
成程、成程。ありがとう!

177 :デフォルトの名無しさん:01/12/01 00:18
>>165
Balanced tree

178 :デフォルトの名無しさん:01/12/01 00:21
>>177
・・・違うと思う。

179 :デフォルトの名無しさん:01/12/01 00:34
Bonsai Tree

180 :177:01/12/01 00:35
>>178
そっか、語源の話ね。セジウィックの本に、
「ここではそれ (註: "B-tree" という語のこと) を "外部探索の
ための平衡木" をさす総称的な用語として使う。」ってな説明が
あったもんで。

181 :デフォルトの名無しさん:01/12/01 01:00
fread や fwrite で読み書きしたいような
バイナリデータのコンテナとしてはなにが適当なんでしょうか?
vector<char> だとoperator (char*)()がないし。
valarrayってのは使ったことないけどどうなんだろ?

182 :デフォルトの名無しさん:01/12/01 01:57
本当はやっちゃいけませんが、
vector<char>::begin() が char* を返してくれるので、これを使えます。

自分はその手の用途のために専用のクラスを作りまひた。。

183 :デフォルトの名無しさん:01/12/01 02:37
>>182
vector<T>::iterator の型が T* とは限らないから、場合によってはまずいです。
書籍 Effective STL の Item 16 に記述がありますが

std::vector<char> v;

このとき v[0] は「最初の要素への参照」を返し、さらに vector はデータを C の配列と
同様のメモリ配置で持ってることが保証されているから、

&v[0]

が確実とのこと。

184 :勉強中:01/12/01 09:47
>>175
とすると foo(const char*)を呼び出すときにfoo(str.data())とやるのはやばいってことですか?

185 :デフォルトの名無しさん:01/12/01 10:05
>>184
foo の仮引数が '\0' 終端されているバイト列へのポインタを想定しているなら、
まずいですね。

186 :184:01/12/01 10:21
>>185
がーん。data()のほうがかっこいいからと思って全部data()でやってた。
OO銀行さんごめんなさい。

187 :浪人:01/12/01 11:46
そうすると「c_str()でなくてdata()を使ったほうがいい場合」っていうのはどういう時ですか?
c_str()で事足りるように思えてしまうんですが・・・

188 :デフォルトの名無しさん:01/12/01 11:52
>>183
> さらに vector はデータを C の配列と
> 同様のメモリ配置で持ってることが保証されている

これは、仕様としては明確に規定されていないらしいのですが、
実装上はこのことが保証されている、と理解してよろしいですか。

189 :デフォルトの名無しさん:01/12/01 11:55
>>187
data() は、内部のポインタを返すだけだけど、c_str() は、
内部データを別のところにコピーしてから '\0' を亜ペン度
する、ってな実装もあるんじゃないかな。

190 :デフォルトの名無しさん:01/12/01 12:01
// 連続するメモリーを獲得する
template <class T> class block {
T *mem;
public:
operator T *() { return mem; };
T &operator [](int n) { return mem[n]; };
block(int n) { mem = new T[n]; };
~block() { delete [] mem; };
};

191 :デフォルトの名無しさん:01/12/01 15:21
>>190
operator T*()は operator const T*() にしようね。
理由はEffective C++参照

192 :デフォルトの名無しさん:01/12/01 15:36
>>191
T operator*() とかんちがいしてませんか?

193 :デフォルトの名無しさん:01/12/01 16:30
イテレータで質問があります

class A
{
};

class B : public A{
};

class C : public A{
};

などとあり、

list<A> li;
B b;
C c;
li.push_back(b);
li.push_back(c);

という感じで格納します。それで、先頭から参照していきたい
のですが

list<A>::iterator it = li.begin();
このitをBやCにキャストして使いたいのですが、どうすればいいのでしょう?

194 :デフォルトの名無しさん:01/12/01 17:25
>>193
無理です。

そもそも list<A> li と書いた時点で li は A 型のデータを格納するコンテナとなります。
したがって

 li.push_back(b);

この時点で li にはスライシングされた(b から A 型のデータ部分だけ抜き出した)デー
タが作成され、li に格納されてしまいます。B 型固有のデータは失われてしまいます。

多態を使いたい場合には、list<A> ではなく list<A*> を使えば OK です。それから仮想
関数を定義しておけば、キャストするまでもなく多態が実現できますよ。

195 :193:01/12/01 17:28
>> 194
レス、ありがとうございます。やはりムリでしたか。
ポインタにして、いろいろやってみます。

196 :デフォルトの名無しさん:01/12/02 13:52
vector<int> x;
x.resize(5);

とかやったとき、x[0] などの値ってどうなってるんですか?
ゴミ値?

197 :デフォルトの名無しさん:01/12/02 16:05
>>196
引数なしコンストラクタを起動した状態。
intならゴミじゃないかなあ、正確には知らないけど。

198 :デフォルトの名無しさん:01/12/02 18:32
hage

199 :デフォルトの名無しさん:01/12/02 21:24
>>197
int() は 0 だよん

200 :デフォルトの名無しさん:01/12/03 02:36
>>199
ちょっと STL から話がずれるけど、組み込み型のデフォルトコンストラクタの仕様って、
なぜ、ああなってる(int() が不定ではなく 0 となる)のか分かります?

201 :デフォルトの名無しさん:01/12/03 06:41
そうなのか、知らなかった。

202 :デフォルトの名無しさん:01/12/03 09:54
>>200 なぜにsage進行?
1.テンプレートにて xx = T(); のような記述はざらにある
2.テンプレートにて T は組み込み型が指定されることもある
3.よって、組み込み型の*明示的なコンストラクタ*は必要
4.その値は、わざわざ不定とするより 0 とした方が合理的(静的変数も0初期化だから)
という議論でそうなっていると思った。
C++3rd,Stroustrup の 6.2.8 にそれらしきことが書いてある。

203 :デフォルトの名無しさん:01/12/03 17:12
組み込み型のメンバ変数に対しては、明示的に指示しない限り
デフォルトコンストラクタは呼ばれないので注意。一応、為念。

204 :デフォルトの名無しさん:01/12/03 18:19
sage

205 :デフォルトの名無しさん:01/12/04 03:46
>>202
sage たのは STL っつーより C++ 一般の話だからスレ違いかなー、と思ったんで。
おもいっきり STL の話だったね。

> 1.テンプレートにて xx = T(); のような記述はざらにある
> 2.テンプレートにて T は組み込み型が指定されることもある
> 3.よって、組み込み型の*明示的なコンストラクタ*は必要

これで int() を 0 にしなければ、コンストラクタ呼び出し部分のコードとか最適化の
過程で削れそうだよなと思ったんだ。

でも、良く考えたら reserve() と resize() を正しく使い分けてれば、そもそも余計な
デフォルトコンストラクタ呼び出しは発生しないね。

206 :デフォルトの名無しさん:01/12/05 01:02
マ板的には JAVA genericsってどう思う?

207 :デフォルトの名無しさん:01/12/05 01:12
便利そうだなー、と思う。
やはりコード爆発の問題などあるんだろうか?

208 :デフォルトの名無しさん:01/12/05 01:51
>>207
リフレクション機能使ってgenericsを実現してるはずだから、コードの爆発はないと思われ。
C++で例えるなら、 void* 型のコンテナ用意して、dynamic_cast する部分を template 使って実装してるってことね。

ちなみに、C#にもgenericsをつける案はある。

Java Generics
ttp://jcp.org/aboutJava/communityprocess/review/jsr014/

Generics for C# and .NET CLR
ttp://research.microsoft.com/projects/clrgen/

209 :207:01/12/05 04:06
>>208 サンクスコ

210 :202:01/12/05 09:16
>>205 int() は確かにコンストラクタだが、
それの呼び出しオーバヘッドなど無いも同然のはず。
それこそ最適化により定数0に置き換わってしまう。
ちなみに、
vector<int> x;
x.resize(5);
よりは、
vector<int> x(5);
と書く方がベター。

211 :デフォルトの名無しさん:01/12/06 01:43
最近、STLを使い始めたんですが、ちょっとしたことで悩んでいます
今、実験してみたんですけど

vector<int> a(40);
int b[40];
cout << "a = " << sizeof(a) << endl;
cout << "b = " << sizeof(b) << endl;

のようなプログラムの結果が

a = 16
b = 160

だったりするんだけど・・・なぜ??
というかクラスのメンバ変数とかに使っていても問題ないのかなぁ?
なんか変なところのメモリ領域をぶっ壊してなければいいんだけど・・・
ちなみにVC++6.0です。
外出だったらスマソ

212 :デフォルトの名無しさん:01/12/06 01:51
>>211
あってんじゃん。

std::vectorの仕組みわかってる?
allocatorってなんかしってる?

213 :デフォルトの名無しさん:01/12/06 01:51
>>211
> だったりするんだけど・・・なぜ??
そりゃ vector は可変長にするために、固定長の配列をメンバとして持ってないから。
VC6 の vector だと、メンバ変数は

_A allocator;
iterator _First, _Last, _End;

これだけ。各 4 バイトで計 16 バイト。

自分で可変長配列を書くことを考えてもらえれば良いんだが、たとえば char の可変長
配列なら

char *buf;
int capacity, size;

ぐらいをメンバ変数に持たせて、buf[xxx] という固定長配列は使わんでしょ?

214 :デフォルトの名無しさん:01/12/06 01:52
>>211
vectorは常にヒープに保持データを持っているから。
destructorが呼ばれたらdeleteなりなんなりしてヒープを
開放すると。

215 :デフォルトの名無しさん:01/12/06 01:54
わーい、みんなでかぶってる(藁

216 :デフォルトの名無しさん:01/12/06 02:04
こうして211は自分がいかに厨房な質問をしたのかを知り、
質問する前に自分で調べるクセがつくのだ… と信じたい今日この頃。

217 :名無しさん@Emacs:01/12/06 02:05
うぉ,漏れも書いた所で念のためリロードしたら皆かぶってやがんの(汁

そんでも一言.
前者は sizeof(vector<int>) で,後者は sizeof(int[40])って事 > 211

218 :211:01/12/06 02:14
>212-217
たくさんのレスサンキュウ。
たしかに厨房といや厨房なんだけど、調べるにしてもとっかかりがなくて・・・
これで自宅へ帰ってゆっくりと調べられます。ありがとう

219 :デフォルトの名無しさん:01/12/06 03:14
>>218
> 調べるにしてもとっかかりがなくて・・・
ルーク、ソースを使え。

220 :デフォルトの名無しさん:01/12/06 03:53
May the Source be with you.

221 :デフォルトの名無しさん:01/12/06 07:31
あるコンソールプログラムを作ろうと思い、Cスタイルで、と思っていたが
やっぱりカプセル化の恩恵に預かろうと思い、クラスを作り出す。
そのうちSTLの存在を知り、文字列をbasic_stringにすることを決意。
さらに、独自で作成した双方向リストもSTLに・・・・・・キリがない。

222 :デフォルトの名無しさん:01/12/06 07:53
STLを何も考えずに使ってると馬鹿になるよ。

223 :デフォルトの名無しさん:01/12/06 10:29
STLを知らずに同じものを作ってるのは馬鹿だな。

224 :デフォルトの名無しさん:01/12/06 10:55
>>222
まあねぇ。
STLの中身ってアルゴリズムの勉強用にはうってつけだし。

でも、VC++についてるSTLは中身見れた代物じゃないから
STL Portかなんかの中身見るのが賢明。

225 :デフォルトの名無しさん:01/12/06 13:25
>>223
場合によると思うけど。
趣味でプログラム書いてるのなら車輪の再発明でも全然悪くない気がする。

226 :デフォルトの名無しさん:01/12/06 13:58
>>222
STL を「何も考えずに」使うと、落とし穴にはまって死ぬことになってます。
C++ だし。

227 :デフォルトの名無しさん:01/12/07 20:49
C++のlistのsort関数にバグがあるのって有名な話ですか?

228 :デフォルトの名無しさん:01/12/07 21:11
>>227
いいえ。

特定の処理系の話をしてる、それとも ANSI C++ の「仕様」にバグがあると
言ってる?

229 :227:01/12/07 21:37
ごめんなさい VC++の話です。
以下のプログラムが思った動きをしないことを見つけました。
0から32767がソートされて出力されると思うのですが?
32767が32766だと出力されます。
ソート関数の中を見ると確かに間違っているように見えるのですが
もしかしたら仕様なのか?

#include <list>
#include <iostream>

using namespace std;

void main()
{
int i;
list <int> wlist;
for( i = 32767 ; i >= 0 ; --i )
{
wlist.push_back( i );
}

wlist.sort();

for( list<int>::iterator ite = wlist.begin() ; ite != wlist.end() ; ++ite
)
{
cout << (*ite) << "\t";
if( (*ite)%10 == 9 )
cout << endl;

}

}

230 :デフォルトの名無しさん:01/12/07 22:58
>>229
とりあえず VC6 + STLport 4.5 だと 32767 まで表示されます。VC の STL が
バグってるんじゃないかなぁ。(gcc 2.95.3, Borland C++ Compiler 5.5.1 も問題
なし)

231 :227:01/12/07 23:32
そうですか やはりバグようですね。
一応自分で修正したけど内容がいまいち理解しきれてなかったのでGoogleなどで
検索してみたのですがバグがあるって記述も見つからず、会社のPCなので他の
処理系を入れて比べることができなくて、もしかして仕様? とちょっと不安だっ
たのでとりあえず安心しました。 ありがとうございます。

232 :デフォルトの名無しさん:01/12/08 07:04
>>231
http://www.dinkum.com/vc_fixes.html
直すべし。

つーか、SPに入れてくれよ。>MS

233 :デフォルトの名無しさん:01/12/08 09:44
(゚д゚)

234 :デフォルトの名無しさん:01/12/08 23:34
>>232 そのdinkumのパッチでsortも直るの?
それに、dinkumのパッチとVC6のSP5は衝突しているヘッダがあって、
どっちを取るか悩ましいっす。
つーか、STLportを使うべきか。

235 :デフォルトの名無しさん:01/12/09 01:18
> つーか、STLportを使うべきか。
その方が、何かと幸せだと思われ。

236 :デフォルトの名無しさん:01/12/09 01:32
STLport/SGI STLを使わない理由がわからん。

237 :デフォルトの名無しさん:01/12/09 01:39
STLportって、list以外はdinkumに比べてちょっと遅くない?

238 :デフォルトの名無しさん:01/12/09 01:44
実際に計ってみて遅く、
しかもその遅さが許容範囲を超えるならdinkum patchを宛ててそっちを使え。

239 :デフォルトの名無しさん:01/12/09 02:53
そういえば対したことじゃないから忘れてたんだけど、
random_shuffleが元と同じには絶対ならないのって仕様?

(1 2 3 4 5)てsequenceをrandom_shuffleすると
絶対(1 2 3 4 5)にはならないってことね。

とりあえず2回random_shuffleすることにして回避したけど、そのときは。

240 :234:01/12/09 03:10
>>236 STLportへいきたいのはヤマヤマなれど、
発注元の意向とかイロイロあるのです。
MSから出ていれば説得できるんだが。

241 :デフォルトの名無しさん:01/12/09 14:08
発注元の上の方の人に相談するのはダメ。
技術的な相談は、下から。
下っ端の、技術一本でやってる人つかまえて
たばこでも吸いながらマターリと、
付録のSTLをこき下ろそう。

242 :234:01/12/09 21:10
技術的な相談は通っているけど、
問題はそういうことではなくて、
誰が責任をもつか、ってことなんだな。

243 :デフォルトの名無しさん:01/12/09 23:57
>>242
うーん、

 VC の STL (Known Bug あり) を使うと MS が責任をとってくれるの?
 STLport を使わずに自作すれば、上の人が責任をとってくれるの?

と考えると、俺は STLport 使うように説得した方が良いと思うけどな。STLport はフリーだけど
品質はかなり高いよ。

もし金を払ってサポートを買いたいって話なら http://www.stlport.org/services.html に情報が
あるから、そちらもどうぞ。

(これ以上は技術と関係なくなりそうだから、プログラマー板かな)

244 :デフォルトの名無しさん:01/12/11 21:13
C++相談室でSTLスレ逝けと言われたのでこっち来ました。

STLport好きな人、教えてください。
STLportを使った自分のプロジェクトに、VC++6標準のSTLを使ったライブラリ(*.libと*.hが利用可能)を
組み込もうとしたんだけど、上手くいかないんですよう。リリースビルド時に例外起こして逝きます。
デバッガで追いかけてみたらdelete時にメモリ破壊してました(debugビルド時は平気)。
ライブラリのヘッダの
#include <vector>
でSTLportの方のvectorがincludeされてしまい、おそらくそれが原因では無いかと思っておるのですが。

245 :デフォルトの名無しさん:01/12/11 21:17
オプションのディレクトリのインクルードファイルのとこを見てみなさい。
STLportが一番下ならSTLportが試用されていない。
STLportが一番上ならSTLportが試用されている。

libと同じ設定でビルドしなさい。

246 :デフォルトの名無しさん:01/12/11 21:33
>libと同じ設定でビルドしなさい。
すみません、それってlibと同じようにVCのSTL使えって事デスカ?

STLportのディレクトリ設定は、コンパイラに引数で渡してますので最優先で検索されてます。

247 :デフォルトの名無しさん:01/12/12 15:40
>>244
STLport は確かマクロを定義すると、ネームスペース std:: ではなく stlport: に閉じ込められるはず。
そうした上で std::vector() と stlport::vector() を別モノとして区別して使うしかないと思われ。

vector なんかを include するときには、諦めてフルパスで 2 つ書くか、STLport の方にはパスを切
らずに、親ディレクトリにパスを切って

#include <vector>
#include <stlport/vector>

みたいに使うとか。(試したことないけど)

248 :デフォルトの名無しさん:01/12/20 00:13
カスタムアロケータを実装する時に参考になる書籍とかウェブサイト
ありませんか?日本語だと嬉しいのですが

249 :デフォルトの名無しさん:01/12/20 00:25
すみません、クラスのインスタンスの保存で質問なのですが・・・
class a{
proteted:
char b;
int c;
};
class d{
public:
vector<a> e;
};
int main(){
d* D=new d();
a A;
D->e.push_back(A);
int fh;
fh=_open(....,....,...);
//Dをwriteしたい
_close(fh);
return 0;
}
で、Dの内容を書き込みたいのですが、クラスのベクトルを含んだサイズを取得するにはどうすればよいのでしょう。

250 :名無しさん@Emacs:01/12/20 00:38
>>249
for_each(D->e.begin(), D->e.end(), hoge());

って感じで hoge() で書き込む処理を書いとくんじゃだめかい?
# ビミョーに主旨と違う答えな気もするけど

251 :デフォルトの名無しさん:01/12/20 00:53
「クラスのベクトルを含んだサイズ」が分かったとして、あとどうするの?

252 :デフォルトの名無しさん:01/12/20 01:03
>251
write(fh,D,sizeof(D));だったら、ベクトルの中身まで保存されないのです。。。

253 :デフォルトの名無しさん:01/12/20 01:31
>>248
http://www.josuttis.com/cppcode/allocator.html

254 :248:01/12/20 02:15
>>253
ありがとうございます
なかなかシンプルですね(w もうちっと詳しいのどこかに無いかなあ

書籍なんかでもほとんど解説が無いのですがカスタムアロケータって
こういうものでしょうか?

255 :デフォルトの名無しさん:01/12/20 02:52
>>254
Effective STL の Item 11.

4 page 弱だが、最低限必要なことは書いてあると思われ。

256 :デフォルトの名無しさん:01/12/20 06:35
>>249 >>252
基本的にポインタが含まれるクラスや構造体をバイナリイメージのまま保存しても、ポインタ値が保存されるだけでその参照先は保存されないので、意味がないです。
必要な要素を1個ずつ地道に保存しましょー。

257 :デフォルトの名無しさん:01/12/21 08:24
>>254
Modern C++ Design は?

258 :デフォルトの名無しさん:02/01/06 17:31
STLはこっちで議論しろage

259 :デフォルトの名無しさん:02/01/06 17:35
STL、すっごい便利なものだとは思うが
いざ使おうとなると、
???。

260 :名無しさん@Emacs:02/01/06 18:35
Effective STL ってまだ日本語訳出ないの?

261 :デフォルトの名無しさん:02/01/08 01:28
VCのSTLとSTLPortで、
string s1, s2="abc";
s1.assign(s2, 0, s2.size()+1);
if("abc" == s1)
cout << "success" << endl;
else
cout << "failure" << endl;
s1.assign(s2.c_str(), s2.size()+1);
if("abc" == s1)
cout << "success" << endl;
else
cout << "failure" << endl;
を実行した結果が
 success
 failure
になるんだけど、stringの仕様的にはこれってありなんですかねー?
なんでこうなっちゃうのかはわかるんだけど、
stringの仕様がいまいちわからん。

262 :デフォルトの名無しさん:02/01/08 02:00
>>261
std::stringはヌル文字終端ではなく、サイズとデータの組で扱うものなので
(中にヌル文字を含められる)
後者が不一致なのは正しいよ。

263 :261:02/01/08 02:08
すばやいレスどうもありがとうございます。
下が不一致なのは分かるのですが、
上が一致するのは正しいのでしょうか?
というか一致させなければならないのでしょうか?
最近stringクラスを自作していて疑問に思ったもので・・・

264 :デフォルトの名無しさん:02/01/08 02:14
>>263
stringからassignした場合、size()より大きな長さ指定しても
size()で丸められるからだよ。

265 :261:02/01/08 02:19
>>264
しかし、ポインタからでもchar_traits::length等で
長さを取得し、丸めることはできると思うのですが・・・
ここら辺は効率、ということなのでしょうか?

266 :デフォルトの名無しさん:02/01/08 02:20
>>265
ポインタからでサイズ指定がある場合は
ヌル文字終端とみなさないでデータブロックとみなすからじゃないかな。

267 :261:02/01/08 02:25
>>266
やっぱ、そうなんですかねー・・・
しかし、STLは奥が深いですねー

268 :デフォルトの名無しさん:02/01/08 02:26
>>267
そうでないと「ヌル文字を含むことができる」という仕様なのに
それに適合するデータブロックを設定することができなくなるし。

269 :261:02/01/08 02:30
>>268
個人的にはあそこの引数にはC文字列しか渡せないのかと思っていたので・・・
色々ありがとうございました。

270 :デフォルトの名無しさん:02/01/08 02:39
>しかし、STLは奥が深いですねー
stringはSTLじゃないよ

271 :261:02/01/08 02:43
>>270
よく見てますねー(汗
確かにちがいますね。失礼しました。
STLじゃないということで気がついたんですが、
complexクラスの詳しい使い方等知っていらしゃいませんかねー、となたか?
できれば日本語でプリーズ

272 :デフォルトの名無しさん:02/01/08 03:00
basic_stringは今みるとsgi STLにも入ってるような。
それとはもかくcomplexもSTLだっけ?(笑)

でcomplexだが、VCあるならhelpみれば分からん?

273 :261:02/01/08 03:14
>>272
半分くらいしかわからないのは、数学力が無いせいなのでしょうか・・・(汗
一から出直してきます・・・

274 :std::string:02/01/08 19:40
std::stringをメンバ変数に持ったクラスをdll(非MFC)にしたときに発生する
以下のWarningって防ぎようがないんでしょうか?

warning C4251: 'm_strName' : class 'std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' は __export キーワードを使って class 'Test' にエクスポートし
てください。

dllにできないばっかりにMFC(CString)は使いたくないんですが・・・

275 :デフォルトの名無しさん:02/01/08 19:52
>>274 VC++6の標準ライブラリを使ってるのだよね?
DLL生成において -MD 指定してる?

276 :デフォルトの名無しさん:02/01/08 19:54
_TCHARみたいに_UNICODEがdefineされてる場合は「wchar_t」されてない場合は「char」
みたく、stringが展開される標準のマクロってないんですか?
たとえば、_STRINGにしておけばUnicodeの切り替えが簡単にできるとか

277 :std::string:02/01/08 20:28
>>275 ありがとうございます。

/MDじゃなくて /MTDになってました。(デバッグ用ライブラリみたいです)。
/MDに変更したら、うまくいきました。

MSVCPRT.LIB マルチスレッド、ダイナミック リンク (MSVCRT.DLL 用インポート ライブラリ) /MD _MT, _DLL

Debug Multithreaded (MTd)

278 :デフォルトの名無しさん:02/01/08 21:29
>>276
std::basic_string<_TCHAR>

279 :デフォルトの名無しさん:02/01/12 01:55
stringの動的配列を作ろうと思って、
vector<string>
ってやったんですが、どうしてもWarningが消えないんです。
(warning C4786,VC++6.0)

皆さんはstringの動的配列を使いたいなぁってときはどうしてますか?

-----
#include <windows.h>

#include <vector>
#include <string>
using namespace std;

int main(int argc, char* argv[])
{
vector<string> vsNames;

return 0;
}

280 :デフォルトの名無しさん:02/01/12 02:05
>>279
その Warning はまともなソース書いててもSTL使ってる限りどうやっても避けれん。
悪いのはプログラマじゃなくてVC++のほう。

#pragma 使って無理やり消すべし。

#pragma warning(disable:4786)

うろ覚えだから書き方間違ってるかも。
MSDNで #pragma の warning について調べてみろ。

281 :デフォルトの名無しさん:02/01/12 02:07
#pragma warning(disable:4786)
VC++でSTL使うときの基本中の基本。つか検索しろよ。

282 :デフォルトの名無しさん:02/01/12 02:07
被ったか。

283 :280:02/01/12 02:18
うが!!消えました。
すみませんです。ありがとうございますです。

284 :デフォルトの名無しさん:02/01/12 23:11
std::bind1st(std::mem_fun_ref(&std::vector::resize()), num)
ってできるようになってくれるといいと思わない?
(上のコードちょっと間違えてるかもしれない(特にmem_fun_refの引数)けど、
その辺は見逃して…

285 :デフォルトの名無しさん:02/01/12 23:14
>>284
すでに何をしてるコードだかわかんないyo!

286 :デフォルトの名無しさん:02/01/13 00:08
>>285
vector の参照 v を渡したときに、

 f(v) の実行 => v.resize(num) の実行

となるような関数オブジェクト f を作りたいんじゃないの。たとえばネストした 2 次元の vector があったときに、
内側の vector に対して、まとめて resize とか reserve したい場合に使える。こんな感じか。

vector<vector<int> > vv;
for_each(vv.begin(), vv.end(), bind2nd(mem_fun_ref(&vector<int>::reserve), 1));
for_each(vv.begin(), vv.end(), boost::bind(&vector<int>::resize, _1, 1));

Borland C++ Compiler 5.5.1 と gcc 2.95.3 で試してみたけど、コンパイルが通ったり通らなかったりだなぁ。
VC6 は void 型のメソッドに対して関数オブジェクト作れないので論外だけど。

287 :デフォルトの名無しさん:02/01/13 02:17
>>286
>VC6 は void 型のメソッドに対して関数オブジェクト作れないので論外だけど。
無駄にbool型にしたりして急をしのいだりした。
あと、VCのせいではないけどmem_fun系で参照の参照がどうたらこうたらというのも鬱陶しい。

288 :デフォルトの名無しさん:02/01/13 11:42
>>273
std::complexなんて思いっきり直感そのままなんだから、
複素数を使いたいんだったら何も悩むこと無いと思うんだけど。
つーか、分からないのに使いたい、というシチュエーションがありえるのか...

#次のスレタイトルは標準C++ライブラリに変更したいね。

289 :デフォルトの名無しさん:02/01/13 21:29
>>287
boost::bind() とか boost::ref() を使うと幸せになれる。

コレクション v に入ってる要素それぞれについて iter->exec(con); を実行したい、ただし con は参照渡し
という場合のサンプルコード。

for_each(v.begin(), v.end(), bind(&Foo::exec, _1, ref(con));

290 :STL消防:02/01/13 21:37
vectorで指定インデックスの要素を削除して
配列を詰める方法どうやるん?

vector<int> ary;
ary.push_back(10);
ary.push_back(20);
ary.push_back(30);
ary.erase(1);

こんなんじゃダメでしょ?

291 :デフォルトの名無しさん:02/01/13 22:13
>>290
vector<T>::erase() の引数は iterator だから、

ary.erase(ary.begin() + 1);

だろう。vector だと begin() で random access iterator を返してくるので、それに +n して n 番目
の要素を指すイテレータが得られる。

292 :290:02/01/14 02:41
>>291
なるほど、begin()に足せばよかったんですね。
実際にやってみたら出来ました。ありがとございました。

293 :STL勉強中:02/01/20 08:11
ptr_fun()をバインダとともに使用したいのですが、うまく働きません。
Borland C++ 5.5.1を使用しているのですが、以下のコードがコンパイ
ルエラーになってしまいます。

void foo(const int &i, const char *s)
{
 cout << s << i << endl;
}

int main()
{
 int d[] = {1, 2, 3, 4 };
 vector<int> v(d, d + sizeof(d) / sizeof(int));

 for_each(v.begin(), v.end(), bind2nd(ptr_fun(foo), "foo:%d"));
}

エラー E2350 C:\Program Files\Borland\CBuilder5\Include\function.h 327: 参照型へのポインタあるいは参照は定義できない(関数 main() )
エラー E2285 C:\Program Files\Borland\CBuilder5\Include\function.h 338: 'binder2nd<pointer_to_binary_function<const int &,const
char *,void> >::binder2nd(binder2nd<pointer_to_binary_function<const int &,const char *,void> >&)' に一致するものが見つからない
(関数 bind2nd<pointer_to_binary_function<const int &,const char*,void>,char *>(const pointer_to_binary_function<const int &,
const char *,void>&,char * const &) )

『プログラミング言語C++第3版』のP.601に似たようなコードが載っ
ているので、いけそうな気がしたんですが、書き方が悪いのかなあ。


294 :名無しさん@Emacs:02/01/20 12:08
>293
何故ダメなのかはちょっと分からないんだけど, foo の引き数を
const int& から int に変えると g++ 2.95.3 ではコンパイル通るよ.
実際,int とかは参照よりも値渡しの方がパフォーマンスいいし,
参照の必要が無いんなら int にしてみては?
# 必要があるんだと・・・どーすりゃいいのかねぇ.

295 :デフォルトの名無しさん:02/01/20 14:32
>>294
boost::bind(), boost::ref() でいけると思うが。

http://www.boost.org/

296 :デフォルトの名無しさん:02/01/20 18:06
Rubyに移行せよ!

297 :STL勉強中:02/01/20 19:33
>>294
> 何故ダメなのかはちょっと分からないんだけど, foo の引き数を
> const int& から int に変えると g++ 2.95.3 ではコンパイル通るよ.

おお。すばらしい。こちらでも通るようになりました。いろいろ試して
はいたんですが参照とは気がつきませんでした。ありがとうございます。

>>295
教科書にも載っている基本的な部分での問題だったので、気になってい
たのですよ。boostは先ほどダウンロードしましたので、余裕が出来た
ところで英語と格闘してみます。

>>296
いや、それはちょっと(^^;


298 :デフォルトの名無しさん:02/01/20 20:41
std::istream_iteratorとostream_iteratorに
transform()を適用したいのですが、可能でしょうか?

299 :デフォルトの名無しさん:02/01/20 22:55
transformの引数はinput iteratorとoutput iteratorだから、規格ではOK。
つうか、調べればすぐわかることだし、やってみればいいのに。

300 :デフォルトの名無しさん:02/01/20 22:58
テンプレート使うと、デバッグしにくくなる気がするんだけど、
気のせいですか?

301 :デフォルトの名無しさん:02/01/20 23:03
>>300
俺は VC6 メインだけど、デバッガ優秀なんで、それほど。

むしろコンパイルエラーが出たときに、エラーメッセージを解読するのが疲れる。

302 :名無しさん@Emacs:02/01/20 23:10
うん,漏れもエラーメッセージがねぇ・・・
typedef した名前を表示してくれるとカナーリ違うと思うんだけど,それは
望み過ぎだよなぁ,やっぱ.
シンタックスエラーで間違った typedef とかが表示されたら尚更ワケワカンネーヨ
状態になっちまうもんなぁ.

303 :302:02/01/20 23:11
sage 忘れた,スマソ

304 :デフォルトの名無しさん:02/01/20 23:24
>>300
疲れる。このブレークポイントはどのテンプレート実体を対象にしたものですか?みたいなダイアログが出てきて少しとまどう。

305 :デフォルトの名無しさん:02/01/20 23:32
デバッグ中、コンテナの中身を確認できないのでやりにくい。
一度、デバッグするために配列にコピしたこともあるけど、ほとんどは
想像でやってる。

306 :デフォルトの名無しさん:02/01/21 00:03
確かに、一般的なコンパイラだと、templateつかうとデバッグしにくい。
templateの最大の欠点だと思う。

でも、しにくいのはコンパイラエラー潰しであって、
ロジックエラーは他と対して変わらないからそんなに気にならない。
コンテナの中身が見難いのはどうしようもないけど。

VC6は便利だけど、templateの実相が甘すぎてtemplate自体が使いにくい。
規格通りのコンパイラがあればいいんだけどねえ。

307 :デフォルトの名無しさん:02/01/21 01:10
>>299
いや、書き方が悪かった。
transform()の第二引数が、istream_iteratorのケツなんだけど、
それを得る方法がない、の意です。



308 :デフォルトの名無しさん:02/01/21 01:14
>>300
g++だと最低だね。慣れるまでとてもヨメネー。

309 :デフォルトの名無しさん:02/01/21 02:07
小ネタを、
引数つきコンストラクタいろいろを犠牲にしていいなら、
typedef std::vector<MyClass> MyVector
↑より↓のが、シンボル短くていいぞ。
class MyVector : public std::vector<MyClass> {};
役に立つ?

310 :299:02/01/21 07:15
>>307
ごめんなちゃ〜い。ちょっと考えて読めばわかりますね。勘違いでちた。
で、回答(試してないけど)ですが、istream_iteratorをデフォルトコンストラクタで作ると、
それがファイル終端になるはずです。記憶違いじゃなければ。
途中で止める方法は、しらない。

311 :デフォルトの名無しさん:02/01/21 18:08
VC++6のツール->オプション->ディレクトリのインクルードファイルに
.../STLport4.5.1/stlportを指定して最上段に置いたんですが、
コンパイル時に

_site_config.h(51) : fatal error C1189: #error :
"Only multi-threaded runtime library may be linked with STLport!"
cl.exe の実行エラー

なるものが出ます。
STLportの導入って何か他にすべきことがあるんでしょうか・・・。

312 :デフォルトの名無しさん:02/01/21 18:16
エラーよめよ。
C/C++ コード生成 使用するランタイムライブラリを
マルチスレッド系にしる!っていわれてんだよ。

313 :311:02/01/21 18:20
>>312
ありがとう(TдT) ついでに聞かせておくれ。
使用するランタイムライブラリの変更ってどこでできるのですか・・・。


314 :313:02/01/21 18:24
はうっ。判りました。ありがとう〜。

315 :デフォルトの名無しさん:02/01/21 19:09
>313=314
せめてどうやったかぐらい書くのが礼儀だろ.

316 :デフォルトの名無しさん:02/01/21 19:30
>>314
そんなんもわからん奴がSTLport使おうとすること自体なんか間違ってると思われ。
いや、STLport使うことで面倒が減るという点において良い効果があることは当然なんだけどね。

317 :デフォルトの名無しさん:02/01/21 19:46
>>312
シングルスレッドで iostream も要らんのなら

#define _STLP_NO_OWN_IOSTREAMS 1
#define _STLP_NO_THREADS 1

とかもアリ。

318 :311:02/01/22 01:07
失礼こきました。経過報告です。
『マルチスレッド系にしる』とのことでVC++6のヘルプで調べて
プロジェクト→設定→C/C++→カテゴリ→コード生成→マルチスレッド
にしてコンパイルしたところ上記のエラーは消えました。
# VC++6初心者でどこに何があるか判ってなくてすみません。
で今度はリンク時にstl_port_vc6_static.libがないと言われたので、
STLport4.5.1のsrcディレクトリを見るといろいろあったので
NMAKE -f vc6.makとかして出来上がったlibディレクトリを
ツール→オプション→ディレクトリ→ライブラリファイル
に追加しました。これで動きました。

>>317
ありがとございます。


319 :デフォルトの名無しさん:02/01/22 02:18
なかなか素直でよろしいですな.

ところで Effective STL って訳本出る予定無いんかな?

320 :age:02/01/26 17:58
age

321 :長いかも:02/01/26 22:06
ファイルからの読み出しに関して質問があります。

アスキーファイルから1行づつデータを取り出して、それをstd::stringに放り込みたいと
思ってます。

で、まず以下のようにしました。

std::ifstream fsHoge("hoge.txt");

while( !fsHoge.eof())
{
string strBuf;

fsHoge >> strBuf;

cout << strBuf.c_str() << std::endl;
}

ですが、これはhoge.txtの中身が
aaa bbb ccc
ddd eee fff 111 222 333

のような場合には意図したようになりません。

char szBuf[1024];
fsHoge.getline(szBuf, 1024);
cout << szBuf << std::endl;

とgetlineを使えば実現できるのですが、1行の長さが1024を超える可能性があるので
不安です。サイズを大きめにとっておけばいいのですが、せっかくstringを使ってるのに
ここでchar[]を使いたくないです。

希望としては、

fsHoge >> strBuf;

としたときに、スペースも文字列として認識する方法とかがあればいいなと思ってます。
何かいい方法ご存じないでしょうか?よろしくお願いします。

322 :デフォルトの名無しさん:02/01/26 23:06
>>321
string::getlineはどうよ?
 template<class E, class T, class A>
 string::basic_istream<E, T>& getline(basic_istream <E, T>& is, basic_string<E, T, A>& str);

323 :デフォルトの名無しさん:02/01/26 23:37
std::getline()じゃなかったか?
while (getline(fsHoge, strBuf)) {
 cout << strBuf << endl;
}
みたいな。

324 :長いかも:02/01/26 23:56
getlineでできましたぁ。
ありがとうございました。>>322 >>323

while (getline(fsCurrentMail, strBuf)) {
cout << strBuf.c_str() << endl;
}

これでchar[]の呪縛から逃れられますです。

325 :デフォルトの名無しさん:02/01/27 00:38
なぜに
cout << strBuf.c_str() << endl;
なの?

326 :デフォルトの名無しさん:02/01/27 00:51
>325
漏れもそれは気になってた

327 :長いかも:02/01/27 01:10
>>325
>なぜに
> cout << strBuf.c_str() << endl;
> なの?

あれ?昔stringをそのまま放り込んだらエラーになった経験が・・・

328 :長いかも:02/01/27 01:13
自己レス

> あれ?昔stringをそのまま放り込んだらエラーになった経験が・・・

すみません。
#pragma warning(disable:4786)

を入れる前の話でした。


329 :STL勉強中:02/02/05 23:55

boostを試してみました。コンパイラは以前に引き続き、Borland C++ 5.5.1
を使用しています。とりあえず以下のようなコードを書き、1)の部分を
いろいろいじくってテストしてみました。

  vector<vector<int> > vv;

  vv.resize(4);
1) for_each(vv.begin(), vv.end(), boost::bind(&vector<int>::reserve, _1, 10));

  transform(vv.begin(), vv.end(), ostream_iterator<int>(cout, ","),
    boost::mem_fn(vector<int>::capacity));
  cout << endl;

この状態だと期待通りの動きをしています。次にboostを使わず

2) for_each(vv.begin(), vv.end(), bind2nd(mem_fun_ref(&vector<int>::reserve), 11));

としてみると、コンパイルは通るのですが、reserve()は実行されてい
ないみたいで、結果が

0,0,0,0,

となります。まあ1)で動いているので問題はないのですが。これは
mem_fun_ref()に問題があるのかなと思い、代わりにboost::mem_fn()を
使用してみました。

3) for_each(vv.begin(), vv.end(), bind2nd(boost::mem_fn(&vector<int>::reserve), 12));

するとコンパイルも通らなくなります。std::bind2nd()の方の問題なの
かな?

最後にresize()も試してみました。

4) for_each(vv.begin(), vv.end(), boost::bind(&vector<int>::resize, _1, 10));

> 致命的エラー F1004 mem_fn.cpp 18: コンパイラ内部のエラー(関数 main() )

ぎゃふん。


330 :デフォルトの名無しさん:02/02/06 00:11
Effective STL どうだった?


331 :デフォルトの名無しさん:02/02/06 01:36
>329
g++ 3.0.3 だったら以下のコードでキチンと動いたよ
# g++ 2.95.3 はコンパイル通らず
vector<vector<int> > vv;
vv.resize(4);
for_each(vv.begin(), vv.end(), bind2nd(mem_fun_ref(&vector<int>::reserve), 11));
transform(vv.begin(), vv.end(), ostream_iterator<int>(cout, "\n"),
     mem_fun_ref(&vector<int>::capacity));

>330
買い

332 :デフォルトの名無しさん:02/02/06 03:58
>>329
http://www.boost.org/status/cs-win32.html によると BCC のクリア率は2位
1: (65) GNU GCC2.95.2-6
2: (63) Borland BCC 5.5.1
2: (63) Metrowerks CodeWarrior 7.0

Pass を1として数えた値。満点は71。ちなみに
Intel Intel C++ 5.0 と Microsoft VC++ 6.0 SP5 STLport 4.0 が 56 でどんじり。
コード生成以外は同じコンパイラかしら。


333 :デフォルトの名無しさん:02/02/06 10:56
>>330
すぐに買って読むべき。

334 :デフォルトの名無しさん:02/02/06 18:02
STLをVC++6.0でつかってます。
ぶっちゃけた話、STLでは正規表現は使えないのでしょうか?
たとえば、
string strAddress="<aaaa@bbb.ccc.dd>";

strAddress.trans("<([a-zA-Z@.]+)>","$1","g");
cout << strAddress << endl;
---
<結果> aaaa@bbb.ccc.dd

みたいなことはできないのでしょうか?

335 :デフォルトの名無しさん:02/02/06 18:05
>>334
STLほんとに使ってるのか? STLって何か知ってるのか? と突っ込んだ上で、
boost使え。

336 :デフォルトの名無しさん:02/02/06 18:30
>>330
つーか買え!



337 :デフォルトの名無しさん:02/02/06 18:37
>>335 ども。
なるほど。標準ではやぱりないんですね。残念。
MFCと、
http://www.boost.org/
のライブラリって、ぶっちゃけた話どっちが信用できるんでしょうか?


> STLほんとに使ってるのか? STLって何か知ってるのか? と突っ込んだ上で、

STL: MFCのCStringをつかわなくても、stringが扱える便利な標準ライブラリ。

338 :デフォルトの名無しさん:02/02/06 18:53
>>337
どっちがって、用途が違うから比較できないだろ。

339 :デフォルトの名無しさん:02/02/06 19:04
>>337
そんな問いをするキミがいちばん信用できません。

340 :STL勉強中:02/02/06 21:16
レスありがとうございます。

>>331
> g++ 3.0.3 だったら以下のコードでキチンと動いたよ
> # g++ 2.95.3 はコンパイル通らず

いまやってみたところ、うちにあるg++ 2.96-81でもコンパイル通りませんでした。
そうか、g++ 3.03か…

>>332
> http://www.boost.org/status/cs-win32.html によると BCC のクリア率は2位

なるほど、bccはまだ優秀な方だったんですね。

> Intel Intel C++ 5.0 と Microsoft VC++ 6.0 SP5 STLport 4.0 が 56 でどんじり。
> コード生成以外は同じコンパイラかしら。

う、MS VC++ と STLportを使おうと考えていたんですが…


341 :デフォルトの名無しさん:02/02/06 23:40
>>339
心情的には
自分の作ったライブラリ > 人のつくったライブラリ

なんだけど、
現実には、

自分の作ったライブラリ < 人のつくったライブラリ

なんだよな。

342 :デフォルトの名無しさん:02/02/06 23:42
MFCは名前がダサダサなので使いたくない。

343 :デフォルトの名無しさん:02/02/06 23:43
ライブラリに限らず、
「他人が使うことを考えて物を作る」

「自分で使うために物を作る」
ってのとでは目的が180度異なるからね。この上にさらに品質の問題が
かぶさるから難しいところだ。


344 :デフォルトの名無しさん:02/02/06 23:47
>>343
俺は広く使われてるライブラリは、それだけ多くの人間の目を通ってるということで
自分のコードよりも信頼してるけど。STLport とか Boost とかさ。

(でも STLport 4.5 では auto_ptr にバグがあって 3 分悩んだが)

345 :デフォルトの名無しさん:02/02/07 03:46
多くの人が食べにくるラーメンは,極端にはずれることもなくおいしいことも多い。
けど,やっぱり自分で作るラーメンは,別だよな。連れはいやがるけど。

って感覚。わかってくれると思うけど。

346 :STL勉強中:02/02/08 21:34
334さんではないですが、boost::regexの練習のつもりでいじってみました。
なんかほっとくとこのスレ下がっちゃうし。

 string s("<aaaa@bbb.ccc.dd>");
 boost::reg_expression<char> e("<([a-zA-Z@.]+)>");
 boost::match_results<const char*> r;

 if (boost::regex_search(s, r, e))
  s.replace(r.position(0), r.length(0), r.str(1));

 cout << s << endl;
---
<結果> aaaa@bbb.ccc.dd


おお。便利だ。

ところで334さんの意図してたのってこんな感じでいいんでしょかね?


347 :デフォルトの名無しさん:02/02/08 23:04
>>346
VC6 + STLport 用にコンパイルしたら山のようにファイルが出来て「げげ」
と思ったけど、勝手に必要なライブラリをリンクしてくれるのね。ついでに

#define BOOST_REGEX_STATIC_LINK

しておくと、スタティックリンクも OK と。

ところで >>346 のコード、#define _STLP_DEBUG の状態でコンパイルすると
boost::regex_search() でエラーが出るんだけど、何故?

regtest.cpp(17) : error C2665: 'regex_search' : 4 のオーバーロードは 1 番目の
引数を 'class _STL::basic_string<char,class _STL::char_traits<char>,
class _STL::allocator<char> >' から要求の型に変換できません。


348 :STL勉強中:02/02/09 08:51
>>347
332さんが上げてくれた
http://www.boost.org/status/cs-win32.html
ここを見ると、VC6 + STLportはboostとあまり相性よくないみたいなん
で、その絡みでしょうかね。


349 :初心者:02/02/09 20:14
お馬鹿な質問ですいません。

C++のSTLって、Javaでいうデザインパターンのことでしょうか?

350 :デフォルトの名無しさん:02/02/09 20:30
>>349
全然違う。

 STL は C++ 標準ライブラリの一部

 デザインパターンは問題解決に有用な、典型的なクラス構成方法をカタログ化
 したもの

351 :デフォルトの名無しさん:02/02/09 20:40
>>348
STLport をデバッグモードにしなければコンパイル通るんだよね。とりあえず

> if (boost::regex_search(s, r, e))
< if (boost::regex_search(s.c_str(), r, e))

と変更して、多重定義されてる別のメソッドを呼ぶように変更したら、デバッグモード
でも通りました。

(STLport のデバッグモードは便利なので、これ使えないと困るんだ)

352 :デフォルトの名無しさん:02/02/09 22:09
boostってg++でも使えます?


353 :デフォルトの名無しさん:02/02/09 22:16
>>352
Linux とか Solaris 上でのテスト結果が載ってる。
http://www.boost.org/status/compiler_status.html


354 :デフォルトの名無しさん:02/02/09 23:10
>>348
VC++6はpartial specializationがないので
基本的にはお手上げ

355 :デフォルトの名無しさん:02/02/09 23:58
boostって漢字だめやんけ。(λλλ...トボトボ)
これだからメリケンは。

356 :デフォルトの名無しさん:02/02/10 00:08
>>355
regex に関しては、ワイド文字列使えば OK だが。

357 :デフォルトの名無しさん:02/02/10 01:19
>>350 
iteratorを用いてcontainerにalgorithmを適用するTemplateライブラリ。
標準かどうかはあまり関係ない。(元HPのJD1979にAlexの独自Libraryを
ANSI-C++に取り込まれただけ、現在はSGIが主体だと思ふ。)
対してDesignPatternsは建築屋さんのAlex(別人)の考えをEricなどがCで
ETを実験的に実装して後に書籍にまとめたのが始まり。Javaか否かは関係ない。
余談だが初期のJavaにはCollectionに共通のOperationを行わせる方法が
標準的には無かった。STLを模したライブラリはあったがTemplateではなく
algorithmの適用が難しい。C++が3rd Editionに成った時はC++はすっかり
別物に姿を変えてしまったがGenericsはhomeogeneousでありC++のような
operatorの乱用はありえないのでSTLを改良したTemplate集がJDK1.5には
つく可能性あり。。それまでSunが生きていればね。と書いてあるUnitTest.




358 :デフォルトの名無しさん:02/02/10 03:02
>>357
その定義だと auto_ptr とか bitset は STL には含まれない?

Effective STL でも STL という単語を
> iteratorを用いてcontainerにalgorithmを適用するTemplateライブラリ。
と定義して使っていたけど、実際には 350 の意味でも使われてるよね。

両方覚えておいて文脈で見極めろ、というのが現実解かと。

359 :デフォルトの名無しさん:02/02/10 03:05
>>357
「てにをは」が正しくないから読みにくいが、自動翻訳にしてはマシなほうかな。

360 :334す:02/02/16 00:00
>>346 久しぶりに来てみたら・・・。どもです。
んだばついでながら参考までにわたくしめの実装を。

bool cutOutUserAndFQDN(string strAdrs, string& r_strUserName, string& r_strFQDN)
{
// メールの正しい形式か
std::string source = strAdrs;
boost::reg_expression<char> regex
= "(^[A-Za-z0-9_][A-Za-z0-9._-]*)@([A-Za-z0-9_][A-Za-z0-9._-]*[A-Za-z0-9]$)";


boost::match_results<std::string::const_iterator> results;
bool found = boost::regex_search(source, results, regex);
if (!found)
{
return false;
}
else
{
strUserName = results.str(1);
strFQDN = results.str(2);
return true;
}
}

もっとまめにくるんだった・・・

361 :334す:02/02/16 00:01
あ、引数にもどしてないや・・・

362 :デフォルトの名無しさん:02/02/17 02:45
ヘンなハナシを振らせてください。

gccやVisual C++6.0の実装のハナシだけど、
ifstream(fd)/ofstream(fd)でファイルディスクリプタを渡せますよね。
これでソケットやパイプに対してgetlineやマニピュレーターを適用できる。
(Visual C++だと_get_osfhandle()なんかでハンドル→ディスクリプタ変換)
さあて、ここで、open/read/write/socket/pipeなんてのは
POSIXでもANSIでもありませんよね。

あと、↓の仕様って妥当だと思うけど、これに外れる実装例ってあるのかしら。

ファイルがコンストラクタまたは open メンバ関数を使って開かれているときだけ、
ファイルはクローズされます。


363 :デフォルトの名無しさん:02/02/17 03:06
まずヘンな日本語を直しなさい

364 :デフォルトの名無しさん:02/02/17 06:42
>362
最終的に何を質問してるやらわからん。


365 :デフォルトの名無しさん:02/02/20 02:16
ヘンなハナシを振らせてください。

gccやVisual C++6.0の実装のハナシだけど、
ifstream(fd)/ofstream(fd)でファイルディスクリプタを渡せますよね。
これでソケットやパイプに対してgetlineやマニピュレーターを適用できる。
(Visual C++だと_get_osfhandle()なんかでハンドル→ディスクリプタ変換)
さあて、ここで、open/read/write/socket/pipeなんてのは
POSIXでもANSIでもありませんよね。

あと、↓の仕様って妥当だと思うけど、これに外れる実装例ってあるのかしら。

ファイルがコンストラクタまたは open メンバ関数を使って開かれているときだけ、
ファイルはクローズされます。

あ、引数にもどしてないや・・・

366 :デフォルトの名無しさん:02/02/20 13:43
>>365 何がいいたいのか、さっぱりわかんない。

367 :デフォルトの名無しさん:02/02/20 14:42
だから
> ヘンなハナシ
なんじゃないの?

368 :デフォルトの名無しさん:02/02/20 14:46
vectorというかSTLはじめてなので、教えて下さい。

struct structField {
string Name;
int CD;
};
vector<structField> items;

items.resize(items.size() + 1, structField);

これって、itemsが破棄されてもstringの文字列が破棄されないっていう、
メモリリークはおきないのでしょうか?おきないなら理由も知りたいです。

369 :デフォルトの名無しさん:02/02/20 14:49
メモリリークしないよ。
string Nameはstack上に置かれるわけで。

# string は typedef 何か* string; されてるわけじゃない。

370 :369:02/02/20 14:50
ところで、そんな構造体使うくらいなら
map<int,string> か map<string,int> か
multimap<int,string> か multimap<string,int> を
使った方がいいとおもうぞ。


371 :デフォルトの名無しさん:02/02/20 14:53
そうなんですか。どうも有難うございます。>>369

もう一つ分からないんですが、
itemsはグローバルになってて、
{
structField structF;
items.resize(items.size() + 1, structF);
}
とかやっちゃうと、スタックだからスコープ抜けると、
itemsのstring Nameの内容は破棄されますか?

372 :369:02/02/20 14:56
されないです。
コンテナに入れる時にコピーされる。


373 :デフォルトの名無しさん:02/02/20 14:58
有難うございます>>372 = 369

itemsが破棄されるときに、スタックのstring Nameが破棄されるのですね。

>>370 = 369
うわ、multimap調べなきゃ。何事も始めは調べることばかりで大変。

374 :デフォルトの名無しさん:02/02/20 15:08
分かったつもりで、分かってなかったんですけど、以下であってますか?

スタックのstring Nameが破棄される、ということは、
コンテナにオブジェクトが入るときは、コピーされたオブジェクトがスタックに入り、
コンテナが破棄されるときに、オブジェクトが破棄される、ということでしょうか?
(あと、stringってオブジェクトになるのかな?)

375 :デフォルトの名無しさん:02/02/20 15:24
コンテナ(vector<T>)が、つっこまれるT型のブツを内部でどう保持してるか
STLのソース(ヘッダファイル)を見てみたらどうです?


376 :デフォルトの名無しさん:02/02/20 15:39
>369
C++でstackって言葉を使うには注意が必要だ
と言うてみるテスト


377 :デフォルトの名無しさん:02/02/20 16:31
あ、stackって、スタック領域じゃなくて、STLのstack?

378 :デフォルトの名無しさん:02/02/20 19:08
STLのソースを説明しようよage。

379 :デフォルトの名無しさん:02/02/20 19:24
>378
どのSTLにするよ?

380 :デフォルトの名無しさん:02/02/20 19:53
>380
そんな難問答えられないよ。

コンテナに入れられるときにコピーされるって、
C++のオブジェクトって簡単にコピー出来るわけ?
Java開発で、オブジェクトのコピー用にcloneメソッドの中身実装した。
意味は理解せずに、規約に沿ってだけど(怖

381 :デフォルトの名無しさん:02/02/20 20:12
dinkum の STL を買おうとしてるんですが
導入後に不具合が出たとかいう話あります?
例のパッチは当ててます。

もう一つ、送付されてくるファイルって
ヘッダ以外に何かありますか?
ライブラリとか差し替えバイナリとか…

382 :デフォルトの名無しさん:02/02/20 20:13
>>381
あるわけねーだろ

383 :デフォルトの名無しさん:02/02/20 20:32
>>380
Fatal error! Too many recursive call.

384 :381:02/02/20 21:13
>>382
不具合が?

385 :デフォルトの名無しさん:02/02/20 21:23
>380
とりあえずC++をきちんと勉強する事をお勧めする.
Java の clone は Java は皆ポインタだから(この表現良く見るけどホントに
この表現でいいんかな) 必要なわけで.


386 :デフォルトの名無しさん:02/02/20 21:39
コピーコンストラクタだってちゃんと実装しないか?

387 :デフォルトの名無しさん:02/02/20 21:59
>385
で、そのあたりのことは、何の本が良いの?
それかサイトとか有りますか?

388 :デフォルトの名無しさん:02/02/20 22:02
>>387
Effective C++
More Effective C++
Exceptional C++

Web サイトだと GotW (http://www.gotw.ca/) が Exceptional C++ の元ネタに
なってる。

389 :385:02/02/20 22:42
>386
まぁそうなんだけどね.でも Java の clone とは意味合いが少し違うじゃん.
どっちも結局は参照の問題ではあるけど.

>387
お約束は388が挙げてくれたけど,オレとしては
C++ FAQ
を結構推したい.最初予備知識無いと意味不明だけど,
何故か読んで行く上で徐々に分かって来る.


390 :デフォルトの名無しさん:02/02/20 23:23
>まぁそうなんだけどね.でも Java の clone とは意味合いが少し違うじゃん.

詳しく教えてYO!

391 :デフォルトの名無しさん:02/02/20 23:25
>>387
じゃ C++Gems/MoreC++Gems もあげとこう。
純粋な C++ だけじゃなくて周辺トピクも扱ってる。
C++FAQ も Gems もトピック形式だから気楽によめてまる。

392 :385:02/02/20 23:50
>390
Java は
b = a;
ってやっても「コピー」じゃなくって,「同じ値を共有する」わけでしょ.
a も b も同じものを指す.
ところが C++ だと本当に「コピー」なわけ.
a と b は全くの別の実体をそれぞれが持つ.

だから,Java は「コピー」すなわち「別物」を作りたい時に実装するのが
cloneであるわけで,C++ のコピーコンストラクタは「メンバにポインタ持っ
てたりする時にそれがそのままコピーされるのはマズイ」とかを回避するため
に必要なもの.

うーん,オレ日本語下手だな.これで通じるかな・・・
まぁコピーコンストラクタとかについては上記の本を読んで行けば分かるはず.

393 :385:02/02/20 23:52
良く考えたらここSTLスレじゃん・・・


394 :デフォルトの名無しさん:02/02/21 00:15
有難うございましす>392

C++だと、
b = a;
で、新しいインスタンスがnewされてbに入るんですか。
言語仕様にインスタンスのcloneが有るわけですね。

395 :394:02/02/21 00:32
違うか。

b = a;
bのインスタンスは既に出来てるからcloneが行われるのか。

396 :デフォルトの名無しさん:02/02/21 02:58
complexで、実部と虚部にそれぞれ独立して値を代入するには
どうすればいいでしょうか?

397 :デフォルトの名無しさん:02/02/21 08:47
a = complex<T>( R, a.imag() ); // aの実部をRに
a = complex<T>( a.real(), I ); // aの虚部をIに

…。(w

398 :396:02/02/21 10:29
やっぱ新しくオブジェクト作るしかないのでしょうか・・・。

399 :デフォルトの名無しさん:02/02/21 10:50
STLport に初挑戦!!
ヘッダだけなのかと思ったらなんかライブラリをmakeしないと
ダメなんだね...
今から make ろう

400 :デフォルトの名無しさん:02/02/21 12:08
dinkum の STL を買って差し替えた場合、実行ファイルの他に
dll かなんかが必要になるとかあるのかな?

仕事に使いたいからそこだけ不安
どうですか

401 :デフォルトの名無しさん:02/02/21 16:28
やっぱり、初心者質問にも優しく答えないとSTLスレッドは盛りあがらないNEage

402 :デフォルトの名無しさん:02/02/21 18:28
>400
メールした方が早いと思われ

403 :STL初心者:02/02/22 01:01
vector、listときてやっとdequeがわかりましたが
何か?(_A_)

404 :デフォルトの名無しさん:02/02/22 01:10
>>403
そろそろC厨を煽れますね
おめでとう。


405 :デフォルトの名無しさん:02/02/22 01:55
age

406 :デフォルトの名無しさん:02/02/22 01:59
ガイシュツかもしれんが、SGIのsetやmapのiterator型って
なんでtreeのconst_iteratorなの?

407 :デフォルトの名無しさん:02/02/22 02:34
>>406
なぜ iterator じゃなくて const_iterator かって話か?

それなら set は「ソート済み」の状態でデータを格納しているわけだが、iterator
経由で要素を書き換えた瞬間に「ソート済み」という前提が崩れる可能性がある
から。

408 :デフォルトの名無しさん:02/02/22 02:52
>>407
なーる。
よく分かったよ。大変参考になった。
ありがとね。

409 :デフォルトの名無しさん:02/02/22 13:25
sgiの質問がでたところで便乗。

sgiのallocatorはオブジェクトでないんですが
これってSTLの標準なんですか?それともsgi独自の考え?


410 :デフォルトの名無しさん:02/02/22 13:31
ヘンなハナシを振らせてください。

gccやVisual C++6.0の実装のハナシだけど、
ifstream(fd)/ofstream(fd)でファイルディスクリプタを渡せますよね。
これでソケットやパイプに対してgetlineやマニピュレーターを適用できる。
(Visual C++だと_get_osfhandle()なんかでハンドル→ディスクリプタ変換)
さあて、ここで、open/read/write/socket/pipeなんてのは
POSIXでもANSIでもありませんよね。

あと、↓の仕様って妥当だと思うけど、これに外れる実装例ってあるのかしら。

ファイルがコンストラクタまたは open メンバ関数を使って開かれているときだけ、
ファイルはクローズされます。

あ、引数にもどしてないや・・・

411 :プル:02/02/22 14:54
行けSTL!あいつを落としちゃえ〜ヽ(` ´
           ≡ 
   ≡≡≡≡△  ▽
 ○         \ |,,☆ 
/|_|\ ≡≡△  ☆,.´☆,\
 /\      \:,☆,;:☆   ▽≡ ←STL


412 :デフォルトの名無しさん:02/02/22 15:09
粘着市ね
410


413 :デフォルトの名無しさん:02/02/22 15:19
スレに意味不明の書き込む人間に前から言おうと思っていたが、注意書きをわざわざ入れてあると言うのに
読まないとは何事だ!!!!!!!読んで意味が理解できないのか、読んでいないのか、読む気がないのかは
知らんが最低限の事は守れ!!!!ここでの管理人はおれだ!!!!!ここでのルール守れない人間はくるな、
邪魔以外の何者でもない、消え去れ


414 :デフォルトの名無しさん:02/02/22 15:44
filebuf と stringbuf ってプログラミング言語C++には書いてないのな


415 :デフォルトの名無しさん:02/02/22 18:31

VC++STLのvectorのerase()って要素を削除した後後ろの要素を
前に詰めてくれるんでしょうか?

416 :デフォルトの名無しさん:02/02/22 18:50
iteratorが返るから注意


417 :デフォルトの名無しさん:02/02/22 18:58
>>409
allocator は STL の標準にふくまれますが、 EffectiveSTL によれば
諸刃の剣(略)だそうです。

>>415
くれます。 MSDN についてくるサンプルコードがよい例です。

>>414
あの本は結構書いてないことが多いですよね。必要なポイントを全部網羅したら
2000ページくらいになるのかな・・・

418 :409:02/02/22 21:02
>>417
あ、すみません。言葉が足りませんでした。allocatorの存在ではなく
allocatorがオブジェクトでないのが標準なのか?
ということを聞きたかったので。

419 :デフォルトの名無しさん:02/02/22 21:27
VC6 の STL って string::push_back がないのな

他になかったり違ったりする点ってある?

420 :デフォルトの名無しさん:02/02/22 21:32
>>413
それはともかく、iostreamでソケットを使用する適切な方法について
どう思う?gccなんかだとファイルディスクリプタをコンストラクタに
渡せるが、ファイルディスクリプタは環境依存なんで、そのまま使うの
が気持ち悪いと思うが。

421 :デフォルトの名無しさん:02/02/22 21:35
>>419
auto_ptr<T>::.reset() もなかった。(ので、さっさと STLport 入れた)

422 :デフォルトの名無しさん:02/02/23 00:16
STLは、ベースがtemplateという時点で終わっている。
実装コードを見れば明らか。

423 :デフォルトの名無しさん:02/02/23 01:35
むしろtemplateであるが故に優れていると思っているのだが

424 :デフォルトの名無しさん:02/02/23 02:56
 質問です。
 WindowsでSTLを使う際、MSVCP60.dllというDLLを呼び出してるんですが、
これって結局なんなのでしょう? "C++ランタイムライブラリ"と説明されてますが、
STLport入れてiostreamを入れ替えたりしてもやはり呼び出してます。
 WinNT4のSP充てる前に入ってるmsvcrt.dll(Cのランタイム)と、VisualStudio6から
もってきたMSVCP60.dllの組み合わせで、エラーが発生して困ってます。
 普通ならmsvcrt.dllをアップデートすれば良い筈なんですが(事実ソレが推奨)、
アップデート入れるなという至上命令のためにひどい難儀してます。
 MSVCP60.dllを呼ばないようにするにはどうしたらいいんでしょう?

425 :424:02/02/23 02:59
 補足。
 ビルドの時にスタティックリンクすれば一応何とかなることは解ったんですが、
ファイルサイズがでかくなるのが困るので……。

426 :デフォルトの名無しさん:02/02/23 03:17
>>424
Dependency Walker を使って MSVCP60.DLL のうち、何を使ってるのか調べて
みれば?

私は Windows 2000 SP2 + VC6 SP5 + STLport 4.5.1 (w/o iostream) を使ってる
けど、そのままだと MSVCP60.DLL にある char_traits や bad_alloc が必要になる
ことが判明したので、

 char_traits, bad_alloc だけ実装した必要最小限の C++ Runtime Library

を作って、それをリンクするようにしました(必要ならソースごと上げるけど)。

私の用途だとその二つだけで済んだけど、場合によっては他の関数も必要に
なるかもしれませぬ。

427 :デフォルトの名無しさん:02/02/23 06:25
STLPortのiostream使ってますか?

iostreamが追加される前から使ってた&サイズが増える、のでなんとなく
避けていたのですが。

STLPortのiostreamを使わないで300KByte程度のアプリが、iostreamを使うと
600KByteになって、なんか負けた気がします。

428 :424:02/02/24 01:16
>>426
いや、Dependency Walkerのほうは知っていたのですが、STL丸ごと入れ替えても
なるものなのかな……と。

 必要最小限の C++ Runtime Library という発想は思いつきませんでした。
同じところがなってるわけでは無いんですが、後学のためにアップお願い出来ますか?

429 :デフォルトの名無しさん:02/02/24 18:16
すまん、誰か詳しく知ってたら教えてちょんまげ。

STLportの4.5.3をVC6でビルドするとき vc6.makとvc6-unicode.makの二つあるけど
どっちを使っても、なんか、unicode/mbcsどちらのプログラムからも使えるようなんだよね。

特に設定もいじらず、(w)setlocaleだけしてる。
文字コードに依存しそうなとこは
basic_string<wchar_t>
basic_string<char>
basic_stringstream<wchar_t>
basic_stringstream<char>
てなかんじで使ってるけど、これって平気?


430 :429:02/02/24 18:16
age忘れんこん

431 :429:02/02/24 18:17
ちなみに、STL-4.0のころは、lib配下のディレクトリにunicode/mbcsそれぞれのlibが出ていたけど、
いまのって一個だけしかでないんだよね。

VC依存の話だけど、教えてーん

432 :デフォルトの名無しさん:02/02/24 19:04
>>431
UNICODEランタイムなんて不要。
なくてもUNICODEのアプリは作れる。
あれはfopenに渡すファイル名がUNICODEかどうかとか
そういう問題で、変換関数はそれに関係なく動く。
別に普通のランタイムでも
wcout << L"あいうえお" << endl;
はちゃんと動作する。
どのみちネットでの通信とかファイルの共有とか
考えると、外部に出力文字コードはiso-2022jpか
シフトJISでないとまずいわけ。

433 :デフォルトの名無しさん:02/02/24 19:04
>>429
vc6.mak と vc6-unicode.mak に差がないしねぇ。

ところで VC6 + STLport 4.5.3 で試してるんだけど、wstring は動いてるんだが
iostream がまともに動いてない気がする。

--
//#define _STLP_NO_OWN_IOSTREAMS
#include <locale.h>
#include <iostream>
#include <string>

using namespace std;

int
main(void)
{
  setlocale(LC_ALL, "japanese");
  wstring s(L"文字列");
  wprintf(s.c_str());         // OK
  wcout << L"日本語" << endl; // NG
  wcout << s << endl;       // NG
  return 0;
}
--

_STLP_NO_OWN_IOSTREAMS を定義して VC6 付属の iostream を使えば
正しく表示される。まぁ、iostream は使わないから、string の類が動けば
構わないんだけど。

434 :デフォルトの名無しさん:02/02/24 19:11
>>433
setlocaleのバグ?こっちならちゃんと動く。

setlocale(LC_ALL, "");


435 :434:02/02/24 19:15
誤爆、読み違え。

436 :デフォルトの名無しさん:02/02/24 19:17
>>434
もしかして src/c_locale_win32/c_locale_win32.c に手を入れないとダメ?
食後にソース読んでみるか。

>>428
char_traits と bad_alloc だけ入れたやつ。
http://www.issei.org/programming/Windows/cpprt/20020223/cpprt.zip

437 :デフォルトの名無しさん:02/02/24 19:38
<algorithm> って案外使い道ないよね…

438 :デフォルトの名無しさん:02/02/24 19:55
>>437
そうか? 先日、数分で書いたコードだが、

http://pc.2ch.net/test/read.cgi/tech/1012536901/n903-908

とかは algorithm がなかったら、遥かに手間がかかってたと思うぞ。

いまさらどうでも良いけど、最後に出力する部分は
> copy(series, series + NELEM(series), ostream_iterator<int>(cout));
の方が良かったかも。

439 :429:02/02/24 20:29
ありがとーん
ほとんどのケースでunicode/mbcsビルドを両方でできるようにしてるんで、
STLportを使う際に「今どっちか」ってのを意識しなきゃいけないようだと大弱りだったんだけど
そんなことないみたいね。

>>432
iostreamは激遅だし必要性もそれほどないので、fileioはstdioを使ってるよ。
結局char_traitsさえしっかりしてればよいということだね。

iso-2022jpとかSJISでないとまずいかどうかはアプリの作り次第なんでとりあえず保留。
内部処理さえunicodeで書ければよいのらー。

>>433
diffをとったらそれほど大差ないように見えたし、ファイルサイズ同じだし、
どちらでビルドしてもよいということなのね。

STLportのwcout/wcinはなんか期待した動きにならないんで使わないようにしてる。

setlocaleの第二引数って、ほんとのところ、何を指定すべきなの?ってのが
いまいちわかってないけど、
_tsetlocale(LC_ALL, _T("Japan"));
でだめ?


440 :デフォルトの名無しさん:02/02/24 20:43
>>437
コンテナを使うことがほぼ前提だからな・・・
string に対する transform() とか equal() くらいしか
ないかもわからんね。

441 :デフォルトの名無しさん:02/02/24 20:48
std::sortとかstd::reverseとかそういうちょっとしたのがうれしかったりして。


442 :デフォルトの名無しさん:02/02/24 20:54
>>441
find, find_if, binary_search, for_each, accumerate あたりも、割と使う。

443 :デフォルトの名無しさん:02/02/25 17:25
>>439
> setlocaleの第二引数って、ほんとのところ、何を指定すべきなの?ってのが
VC6 + 付属の CRT なら

> locale "lang[_country[.code_page]]"
>       | ".code_page" | "" | NULL

と MSDN Library に書いてある。

言語識別文字列 (lang) は、日本語なら "japanese", 国/地域識別文字列
(country) は "japan"、日本語のコードページは 932 だから

 "japanese",
 "japanese_japan"
 "japanese_japan.932"
 ".932"
 ".OCP" (OEM コードページが 932 の環境限定)

どれでも OK でしょう (CRT のソースを読むと、中で EnumSystemLocaleA を
使って列挙したロケール名に対して _stricmp() で比較してるから、"Japanese"
とか "JAPANESE" もアリ)。

このあたりは環境依存で、Solaris だと ja だったり、FreeBSD だと ja_JP.eucJP
だったりとバラバラです。困ったもんだ。

444 :429:02/02/25 18:34
>>443
ありがとんとーーん
"Japan"でいけてたのはVCだからなのね。
改心してJapanese / ja にします

それはさておき、別の問題です。

VC6で、STLport-4.5.3の標準設定のままのときなんだけど、
basic_stringstream<char>を使っていると、
basic_stringstream<char>のコンストラクタがstlのdebugライブラリすでに
あるぞゴルァって怒られます。

よくわからんまま、

stl_user_config.hの_STLP_NO_OWN_IOSTREAMSを1にしてSTLportを
ビルドしようとするとinclude/xxxxなんかねえぞゴルァ!って怒られます。

かといって、プログラムの方で
_STLP_NO_OWN_IOSTREAMSを定義してビルドすると、
basic_stringstreamなんてシランぞゴルァとおこられます。

あちこちのドキュメントにあるように、STLport-4.5.3のiostreamは使わずに
VC付属のiostreamを使うようにするには、どうすれバインダー。

ちなみに今は、STL-4.5.1に戻してます。
なんの問題もないので、このままでいいかとも思ってます。


445 :429:02/02/25 19:28
ごめん、ただの、いんすころーるミスだった。
古いインクルードファイルがVCのincludeの下にあったのが原因みたい。

4.5.3評価体制に移行しる。


446 :デフォルトの名無しさん:02/02/25 22:20
アスキーの「Generic Programming STLによる汎用プログラミング」を読んでて
驚いたんだけど、p43「…入力反復子の範囲内の異なる要素を指す2つの反復子を
使うこともできない。各範囲は同時に単一のアクティブな反復子しかサポート
できない。」とあるのは本当ですか。というか、どういう意味ですか。
これを素直に取ると、first と last という2つの反復子を使えないので、
find なんか実装できないと思うんですが。


447 :デフォルトの名無しさん:02/02/25 22:32
>>446
「サポートする」というのが曖昧なんだけど、単に等式比較をするのは OK だけど
インクリメントするのは NG と主張してるんだと思う。

first == last
++first;

これは OK だが

++first;
++last;

みたいのは NG だと。

448 :デフォルトの名無しさん:02/02/25 22:56
>>447
なるほど。「アクティブ」という語を「++ による移動が可能」という意味だと
考えればよいのですね。あと「デリファレンスができる」という意味も含まれる
かな? 通常、first はデリファレンス可能だけど、last は可能とは限らない
ですよね。
で、「独立した複数のアクティブな反復子はサポートされない」という理解で
よいのかな。


449 :400:02/02/26 11:09
VC に Dinkum の STL 入れたよ
今までのはなにげに warning(disable:) してたのな、再コンパイルしたら
自分のコードに warning 出まくりで鬱

導入は死ぬほど簡単だった

450 :424:02/02/27 00:11
>>436
 うわ、どうもありがとうございます〜。
 参考にして色々やってみます

451 :STL勉強中:02/03/04 11:49

まだ勉強中です(^^;;

勉強の一環としてSTLのアルゴリズムっぽい、かなりてきとーな文字コー
ド変換ライブラリを作成してみました。

作成しながら思ったのですが、なんかこういうのってどっかにありそう
だなあと。皆さん、文字コード変換のライブラリってどんなもの使用し
てます?


452 :デフォルトの名無しさん:02/03/04 12:35
boost::compose_f_gx
とかって,なんでこんなヘンチクリンな名前なの?
fやらgやらhやらって一体何よ,コレ?
名前がヘンテコで覚えにくいYO!!

453 :デフォルトの名無しさん:02/03/04 17:03
>>452
そうか?すげーわかりやすいと思うんだけど。
http://www.boost.org/libs/compose/compose.html

454 :デフォルトの名無しさん:02/03/04 18:15
>>452
これがC++屋の美学なのだから受け入れよう。


455 :452:02/03/05 00:28
>453,454
なるほど.サンクス.

456 :デフォルトの名無しさん:02/03/06 08:29
iterator が指してる中身を取得する方法を教えてください。

457 :デフォルトの名無しさん:02/03/06 08:32
(*iterator).foo

*iterator->foo
だと思うが
後者の使い方って認められてたっけか…

458 :デフォルトの名無しさん:02/03/06 13:14
gcc(g++)についてるSTLってドキュメントどこにあるの?
ううー

459 :デフォルトの名無しさん:02/03/06 14:14
>>458
see /usr/include/g++-xx
  info gcc

460 :459:02/03/06 14:18
ごめん http://gcc.gnu.org/onlinedocs/libstdc++/documentation.html

461 :デフォルトの名無しさん:02/03/06 15:35
>>457
> *iterator->foo
*は余計だろ
iterator->fooは認められてた筈だがコンパイラの実装が追いついていない場合が多いので
結果的に (*iterator).foo と書くことが多いな(w

462 :デフォルトの名無しさん:02/03/06 16:25
class Test{ int i: }:
このクラスを
set<Test*>とするために、operatorを定義したいのですがどう書けばいいのか
わかりません。

set<Test>だったら
bool operator <(const Test &r)const{return i < r.i ;};
としたらOKなのはわかっているのですが。

463 :デフォルトの名無しさん:02/03/06 16:42
map<int,Test*>じゃ駄目ですか?

464 :デフォルトの名無しさん:02/03/06 16:48
>462
こんなのはどうよ?

class Test {
 int i;
public:
 bool operator< (const Test &r) const { return i < r.i; }
};
class Cmp {
public:
 bool operator()(const Test* p1, const Test* p2) { return (*p1) < (*p2); }
};

set<Test*, Cmp> ほげほげ;

465 :462:02/03/06 17:02
>463
>464
どうもです。
Set<Test*,Cmp>でうまくいきました。

466 :457:02/03/06 17:20
>>461
> > *iterator->foo
> *は余計だろ

うはは。間違えた
this と *this の区別で迷うことがあるもんで。鬱出し脳

467 :デフォルトの名無しさん:02/03/07 22:21
g++でこれがコンパイルエラーになるんですが(ヘッダファイルなどは完備)、どっか
間違ってますか?

class A {
public: void foo(int a) {}
};

int main() {
vector<A> v;
for_each(v.begin(), v.end(),
bind2nd(mem_fun_ref(&A::foo), 1));
}



468 :デフォルトの名無しさん:02/03/07 23:01
bind2nd(mem_fun_ref(A::foo), 1)
じゃダメ?

っちゅーか、どんなエラーが出とるんよ?

469 :デフォルトの名無しさん:02/03/07 23:15
>467
vector, bind2nd, mem_fun_ref
に std:: 付けろって話なのでは

470 :469:02/03/07 23:18
for_each もだよな,当然

471 :デフォルトの名無しさん:02/03/07 23:18
>469
ごめん、using namespace std; してます。
g++-3.0.3 だと通ったので、どうやらg++の不具合かな。

g++-2.96 でのエラーメッセージ↓

foo.cpp: In function `int main ()':
foo.cpp:18: assuming & on `A::foo'
/usr/include/g++-3/stl_function.h: In method `typename
_Operation::result_type binder2nd<_Operation>::operator() (typename
_Operation::first_argument_type &) const [with _Operation =
mem_fun1_ref_t<void, A, int>]':
/usr/include/g++-3/stl_algo.h:83: instantiated from `for_each (_InputIter, _InputIter, _Function) [with _InputIter = A *, _Function = binder2nd<mem_fun1_ref_t<void, A, int> >]'
foo.cpp:18: instantiated from here
/usr/include/g++-3/stl_function.h:224: could not convert `(+__x)' to `A
&'
/usr/include/g++-3/stl_function.h:622: in passing argument 1 of
`mem_fun1_ref_t<void, _Tp, _Arg>::operator() (_Tp &, _Arg) const [with
_Tp = A, _Arg = int]'



472 :デフォルトの名無しさん:02/03/08 00:53
あるstd::listのn番目の要素を指すイテレータを得るための、最も美しい方法は
どんなんでしょうか? 教えてください。



473 :デフォルトの名無しさん:02/03/08 01:03
list<T>::iterator it = l.begin();
advance(it, n);

もっとも美しいかどうかわからんけど

474 :デフォルトの名無しさん:02/03/08 01:07
>473
おお、思いつかなかった。
どうもありがとう


475 :デフォルトの名無しさん:02/03/08 01:10
あ、ああ、
それ俺も調べようと思ってた。
さんくすこ


476 :デフォルトの名無しさん:02/03/08 01:23
>>473
std::advance ってなんか好かんデザインだよな。
気持ち的には advance( list.begin(), n ) でイテレータを返してほしい。
advance って名前が適当じゃなくなるけど forward とかで。
473 のやり方が気に食わんって話ではない。念のため。

477 :デフォルトの名無しさん:02/03/08 06:27
>>476
advance() が引数に取るのは入力反復子だから、

InputIterator i, j;
i = advance(j, n);

というのは無駄だって判断なんだろうね、きっと(この直後に ++i とか ++j と
やると、残りの一方の iterator が無効になるから)。

478 : :02/03/09 12:36
質問なんですが、あるコンパイラで

class HogeList : private list<Hoge*>
{
void Add(Hoge *p){push_back(p);}
};

というクラスライブラリを作ったとします。
別のコンパイラで

HogeList l;
l.Add(new Hoge());

とやった場合、動作不良を起こさないんでしょうか?
それともSTLを使ったライブラリはソースを公開するしかないんでしょうか?

479 :デフォルトの名無しさん:02/03/09 12:50
Standard TEMPLATE Libraryだ。

テンプレートがコンパイラにどのように解釈されて、
実行オブジェクトに変換されるのかを理解しなさい。

標準ライブラリと、テンプレートライブラリの違いも理解しなさい。

そしてコレがもっとも大切なことだが、
お前の使っているSTLがどのように実装されているのかを調べて理解しなさい。


480 :478:02/03/09 13:02
>>479
すいません厨なんで、的はずれかもしれませんが、

>テンプレートがコンパイラにどのように解釈されて、
>実行オブジェクトに変換されるのかを理解しなさい。

テンプレートってのは、コンパイル時点で展開されてコンパイルされるんですよね?

>標準ライブラリと、テンプレートライブラリの違いも理解しなさい。

テンプレートライブラリはヘッダファイルに記述されるのが違いでしょうか・・

>お前の使っているSTLがどのように実装されているのかを調べて理解しなさい

STLって、コンパイラごと、バージョンごとに実装が違う可能性ありますよね。
前の質問の補足ですが、STLをDLLに組み込んでも動作不良を起こさないんですか?


481 :デフォルトの名無しさん:02/03/09 13:19
>>480

DLLにしたからといって動作不良を起こすことはないよ。
DLLもEXEも中身は同じだからね。

ただし、STLの実装はコンパイル時のオプション、パラメータによって、
STL用の外部DLLが必要になる可能性があるのでそれは自分で調べなさい。

ちなみに、STLのコンテナクラスみたいのを、DLLのインタフェースに使用した場合
(つまり、関数やメソッドの引数、戻り値に使用した場合)は、
同じバージョンのSTLを同じ条件でコンパイルしてやらないとうまくいかないかもしれん。

同じく、クラスのメンバとして持っている場合や継承している場合も、
同じバージョンのSTLを同じ条件でコンパイルしないとうまくいかないかもしれん。

#違うバージョンのクラスをメンバとして持っているときにsizeof(クラス)をしたとき、
#どうなるか考えてみよう。


482 :デフォルトの名無しさん:02/03/09 13:27
よく見たら、「別のコンパイラで」って書いてあるな。

やめとけ、きっとうまく動かない。
理由は>>481にあるとおり、コンパイル時の条件が違えば、それはきっと
うまく動かない。

なんとかして extern "C" なインタフェースにするか、
WindowsならCOMにすることを考えてみなさい。

今までの経験からいくと、thisポインタをハンドル代わりに使用する
extern "C"なインタフェースが一番「素人にもわかりやすい」実装になる。
CのFILE構造体とfopen/fclose/fwriteみたいなやつね。


483 :478:02/03/09 13:43
>>482
ありがとうございます。
STLは内部だけ(privateメンバにもつのはOK)に使って、
インターフェイス(戻り値、引数など)
STLを継承したクラスなどは不可ということですね。

484 :デフォルトの名無しさん:02/03/09 13:55
いや、メンバとして持つのもやめといた方がいいって。
どうせ持つならポインタにしときなさい。

バージョンやオプションやコンパイラによって
sizeof(std::list<A>)が変わる可能性がある。

だがしかし、同一プロジェクトにおいて、
sizeof(std::list<A> *)が変わる可能性は、おそらく無い。


485 :デフォルトの名無しさん:02/03/09 14:21
STL って実装の完成度のばらつきが大きいような気がしませんか ?
まだまだ成熟してないって事かもしれないけど.

STLport の valarray が何気に遅いような.
他のみなさんのところはどうですか ?

486 :デフォルトの名無しさん:02/03/09 14:22
>>485
速度を重視するならそこだけ別のvalarrayを使おう!


487 :デフォルトの名無しさん:02/03/11 03:40
STLやりたいんだけど、何所から入って良いんだか・・・。

488 :デフォルトの名無しさん:02/03/11 03:47
>>487
イテレータ。

489 :デフォルトの名無しさん:02/03/11 04:10
配列のかわりにstd::vectorを使ってみる

490 :デフォルトの名無しさん:02/03/11 04:33
>>489
覚えるのが楽で、かつ効果大なのは、vector, list, map, set あたりのコンテナと
イテレータのセットかね。次に sort とか size のようなイテレータとセットで働くア
ルゴリズム。

個人的には、あとは auto_ptr も早めに使うことを薦めるけど。

491 :デフォルトの名無しさん:02/03/13 01:55
std::ifstream から文字列を一行づつ読み込みたいのですが、アルゴリズムと
std::istream_iterator<char> か istreambuf_iterator<char> を
使ってスマートに実現するにはどうしたらいいでしょうか? 教えてください。


492 :デフォルトの名無しさん:02/03/13 02:22
>>491
getline() しろよっつー気がするが。アルゴリズムを使いたければ、改行文字か
どうかを調べる述語を作って find_if() とか、どう?

493 :デフォルトの名無しさん:02/03/13 02:27
>>492
>getline() しろよっつー気がするが。
どうもchar文字列を使いたくないのですよ。

find_if()でできます…?ちょっと思いつかないのですが、コード片を
書いて頂けないっすか…


494 :493:02/03/13 02:44
Boost使ってどうにかなりました…。すんません>>492
ありがとう。

ifs.unsetf(ios::skipws);
string mikuDat((istreambuf_iterator<char>(ifs)),
istreambuf_iterator<char>());

boost::char_delimiters_separator<char> sep(true, "", "\r\n");
boost::tokenizer<> tok(mikuDat, sep);
for(boost::tokenizer<>::iterator beg = tok.begin(); beg != tok.end(); ++beg) {
cout << *beg << "\n";
}



495 :デフォルトの名無しさん:02/03/13 03:24
>>getline() しろよっつー気がするが。
>どうもchar文字列を使いたくないのですよ。

std::getlineとchar文字列の関連がわかりません

496 :デフォルトの名無しさん:02/03/13 03:33
え、char hoge[1024];
i.getline(hoge, 1024); と(それに類するもの)以外のインタフェース
ありましたっけ。行長の制限がないような。

直接 std::string で取れるならそっち使います。おしえて495さん。




497 :デフォルトの名無しさん:02/03/13 03:36
って std::getline ????
ナニソレ??


498 :デフォルトの名無しさん:02/03/13 03:38
おお、<string> にあるじゃん。ありがと。


template<typename _CharT, typename _Traits, typename _Alloc>
basic_istream<_CharT,_Traits>&
getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Alloc>& __str, _CharT __delim);

template<typename _CharT, typename _Traits, typename _Alloc>
inline basic_istream<_CharT,_Traits>&
getline(basic_istream<_CharT, _Traits>& __is,
basic_string<_CharT, _Traits, _Alloc>& __str);


499 :デフォルトの名無しさん:02/03/13 06:02
>>496
ストリームのメンバ関数ではなく、テンプレート関数版の getline がある。

500 :デフォルトの名無しさん:02/03/13 06:27
>>499
それが498だね


501 :デフォルトの名無しさん:02/03/13 15:13
もうね、ageちゃう。


502 :499:02/03/13 16:14
>>500
その通りでございます。オフライン状態でキャッシュを見ながら書いてたので、
498 に気づかなかったよ。

503 :デフォルトの名無しさん:02/03/19 00:35
MFC と STL を共存で使うのはやっぱりまずいだろうか?

struct hoge{
  CString foo;
  int bar;
  (略)
};
 とかやって、list::sort()したりとか……

504 :248:02/03/19 01:33
意味が分からん

505 :デフォルトの名無しさん:02/03/19 07:25
いいよ。
sortしたいならきちっとコピーコンストラクタか代入演算子と operator < を定義しておけ。


506 :デフォルトの名無しさん:02/03/30 17:07
定期age

507 :デフォルトの名無しさん:02/03/30 17:08
シマッタ 鬱氏

508 :デフォルトの名無しさん:02/04/06 00:01
ハッシュコンテナってSTL?

509 :デフォルトの名無しさん:02/04/06 00:13
>>508
標準STLには無いと思われ。

510 :デフォルトの名無しさん:02/04/06 03:38
>>508
SGI 版 STL 限定。

511 :デフォルトの名無しさん:02/04/06 11:22
>>510
SGIに準ずる形でSTLportもOK。

512 :デフォルトの名無しさん:02/04/06 11:39
SGIはクソ

513 :デフォルトの名無しさん:02/04/06 12:07
>>512
じゃあ何ならいいのだ?boostか?

514 :デフォルトの名無しさん:02/04/06 14:21
>>513
それ STL じゃないし。

515 :デフォルトの名無しさん:02/04/06 19:09
RogueWaveのSTLが一番クソだと思うが、どうよ?

516 :デフォルトの名無しさん:02/04/06 19:43
>>515
どこらへんが?
あ、煽りじゃないよ。

517 :デフォルトの名無しさん:02/04/06 23:15
SGI/Dinkum/RogueWaveの中で、標準コンテナのパフォーマンスが
一番悪いのはRogueWaveだから。

518 :デフォルトの名無しさん:02/04/07 02:04
STLPortのスレッドセーフって意味のないものだと思いませんか?
使い捨てプログラムに対しては楽かもしれないけど、
実際に移植性も考慮して書くとなると、ライブラリのスレッドセーフに頼ることができないので、
自前で排他制御を行ったりすることになるから。

519 :デフォルトの名無しさん:02/04/07 15:13
>>518
STLport 自体が移植性高いから。

520 :デフォルトの名無しさん:02/04/09 20:51
listの任意の要素をリストの先頭に並べ替えるにはどうしたらいいでしょうか?

list<type>::iterator i;
i = std::find(li.begin(), li.end(), data, pred);
if (i != li.end) {
 li.push_front(*i);
 li.erase(i);
}

これだとコピーコンストラクタを通さないといけないので。
せっかくリストなんだから、要素をつなぎ変えるだけで実現できるような気がするのですが、
その方法がわかりません

521 :デフォルトの名無しさん:02/04/09 20:57
spliceかな

522 :デフォルトの名無しさん:02/04/09 22:04
>>521
ありがとうございます。

>x によって制御されるシーケンスを挿入します。また、x からすべての要素を削除します。この場合、&x は this と等しくないものとします。

しかし、自分の要素を並び替えるのには使えないようです。


523 :デフォルトの名無しさん:02/04/09 22:11
>>552
> この場合
この場合って list::splice( iterator, list& ); の場合だけでは?
3引数とか4引数のバージョンなら行けるはず。

524 :デフォルトの名無しさん:02/04/10 22:57
話題から外れていますが、STLPortをVC++6にインストールしようとして失敗したものです。

copy vc6.mak makefile
nmake clean all
nmake install

しても

ctimeで
../include/ctimeが存在しないとか言われます。落としたファイルが壊れていたんでしょうか。
どこか簡単な解説ページを教えてください。

525 :デフォルトの名無しさん:02/04/10 23:06
>>524
http://karma.pobox.ne.jp/cgi-bin/tiki/tiki.cgi?c=v&p=STL

526 :デフォルトの名無しさん:02/04/10 23:17
>>525どうも。というか今まさにそのページ開いてた…

527 :デフォルトの名無しさん:02/04/10 23:51
#define OBSOLETE 1
はいらない。

#define _STLP_NEW_PLATFORM_SDK 1
はたぶんほとんどの環境で必要

528 :わかってない人:02/04/11 01:32
list<string> ls;
list<string>::iterator p = ls.begin()+1;

なんでこれ、さっきからコンパイル通らねーんだよ。
リストだから +1 されても次のアドレスが
すぐには特定できないってことなんかね。

529 :デフォルトの名無しさん:02/04/11 01:33
std::advance

530 :わかってない人:02/04/11 01:52
>>529
ありがとう。そんなんあったんですね。
イテレータセットした後に、
advance(p, +1);
ってやったら通りました。

ちなみに +1 の場合は p++ と一緒だけど
+2 の場合は p+=2 とは書けないから、そゆとき、
advance を使えってことか。(たぶん)

531 :デフォルトの名無しさん:02/04/11 01:55
>>528
iteratorを理解していないと思われ(w

532 :デフォルトの名無しさん:02/04/12 21:27
>>528
リストのイテレータはランダムアクセスイテレータじゃないんで、+n は出来ないんですよ。
++ で1つずつ進めるしかありません。仕様です。

533 :デフォルトの名無しさん:02/04/12 21:50
 パフォーマンスの問題を意識させるために、あえて加算できないようにしてあるんだよな。確か。

534 :デフォルトの名無しさん:02/04/12 22:26
>>533
そうだったのか。たしかに、演算子オーバーロードで簡単に実装できそうなのに、
なんで出来ないんだろうと不思議に思ってたよ。

535 :デフォルトの名無しさん:02/04/13 00:48
そして advance しかしらない厨房が多発するという罠










にはならんか

536 :デフォルトの名無しさん:02/04/13 09:00
厨房はdistance/advanceを使わずにいちいち先頭からforループ

537 :デフォルトの名無しさん:02/04/13 14:02
>>530
そもそも必要ないのに後置の ++ はヤメレ。

538 :すとらうすとらっぷ:02/04/14 03:40
>>537
うわーん(´Д⊂

539 :デフォルトの名無しさん:02/04/14 17:12
char* strings[] {
"test1",
"test2",
...
};

BYTE test[] = { 't', 'e', 's', 't', '5' }
std::find_if(strings, strings + numof(strings),
 std::not1( boost::bind(memcmp, _1, test, 5) ) );

上のソース、コンパイル通らないんですが、どうすればいいんでしょうか?
std::not1の使い方がおかしいんだとは思いますが・・・

540 :539:02/04/14 17:15
推測ですが、おそらくboost::bind()がunary_functionを継承してないからだと思うのですが・・・
何かいい方法無いでしょうか?

541 :age:02/04/14 18:10
(´-`).。oO(STLってカコイイよなぁ・・・・・)

542 :デフォルトの名無しさん:02/04/14 18:49
>>539
何がしたいのかよくわからないのが、難点ですね。

543 :539:02/04/14 19:01
>>542
strings[]に入っている文字列の中から、
メモリイメージ(終端の'\0'が無い)と一致するものを探したいのですが。

544 :539:02/04/14 19:04
boost::bind()がunary/binary_functionを自動で継承してくれると、
いろいろ使い回しが聞くのに・・・・

545 :デフォルトの名無しさん:02/04/14 19:13
よくわからんけど、boost::not1 じゃだめ?

546 :539:02/04/14 19:22
>>545
bindがunary_functionを継承してないから、それはできません

547 :539:02/04/14 19:37
ちなみに、>>539のソースでtestを文字列として処理するなら、
not1(bind2nd(...))が可能なんですが。
どうも文字列として別バッファにコピーするのが綺麗じゃないので。

548 :デフォルトの名無しさん:02/04/14 19:55
not1の代わりを書いた上で
それをもういっちょboost:bindでくっつけるんじゃ駄目なん?

549 :デフォルトの名無しさん:02/04/14 20:16
>>548
そんなことをするなら、専用の比較関数を書く方がいいだろ。
わざわざbind()なんて使ってるんだから、標準だけですませたいんだと推測

550 :デフォルトの名無しさん:02/04/14 23:38
>>539
 std::find_if( strings, strings + numof(strings),
  boost::bind( std::equal< const char*, const char* >, test, test + 5, _1 ) );
コンパイルはできるっぽいけど、どうよ?

551 :550:02/04/14 23:52
ごめん、なんだかうまくいかないかも、、、

552 :デフォルトの名無しさん:02/04/15 00:06
>>550
lha.obj : error LNK2001: 外部シンボル ""bool __cdecl _STL::equal(char const *,char const *,char const *)" (?equal@_STL@@YA_NPBD00@Z)" は未解決です
herb___Win32_Debug_UNICODE/herb.exe : fatal error LNK1120: 外部参照 1 が未解決です。

コンパイルは通るけど、リンクでエラー発生します。

std::equal<const char*, const char*>, test, test + 5, test);
一度↑のようにするなりして、関数の実体をつくらないといけないようで。
VC以外の処理系ならいいのかもしれませんけどね

553 :デフォルトの名無しさん:02/04/15 00:09
うむ、思いっきり情報出してしまった(藁
まぁ、いいや。

554 :552:02/04/15 00:12
そういえば、以前VC使っていて、関数テンプレートのアドレスが
どうしてもとれなくて悩んだことがあるんだけど、
一度どこかで明示的に実体を作らないといけないと言うことか。

これってVCの制限なのかなぁ

555 :デフォルトの名無しさん:02/04/15 00:14
VCのテンプレートは、最新の規格に追いついてないので
そんなもんかも。


556 :550:02/04/15 00:14
>>552
うん、それがでてこまってたんだけど、実体作りたいだけなんで、
template bool std::equal( const char* , const char* , const char* );
これでオゥゲェらしい。結果も確認できたよ。
g++ で Internal compiler error 373. になるのが気になってる・・・

557 :552:02/04/15 00:24
実体をつくらにゃならないのはVCだけだろうから、#ifdefで囲んじゃえば問題ない・・・かも。

558 :デフォルトの名無しさん:02/04/16 04:08
自前のコンテナクラスとか作るときに
std::_Construct と、 std::_Destroy が便利なんですけど、
これって標準のもの?

559 :STLワッショイ!:02/04/16 04:16
           ρ(´-`ρ)
      ★STL★
(σ´ー`)σ

560 :デフォルトの名無しさん:02/04/16 07:29
>>558
んなわけないでしょ。allocatorを使う。

561 :558:02/04/16 10:37
>>560
じゃぁ自前のアロケーター作るときに(以下同文)

_Destroy(first,last) とかの中見ると、 type_traits<T> 使ってて、
たとえば組み込み型のときは空のインライン関数に特殊化されてるんだけど、
同じ type_traits<T> の仕組みを利用したかったらどうしたらいいんでしょうかね?

自分でループつくって element.~T() とかやってると、
たとえば組み込み型の場合、無駄な空ループが最終コードに残ってしまいます。(g++)

562 :デフォルトの名無しさん:02/04/16 20:19
メモリ確保と解放だけ作って、コンストラクトとデストロイはallocator<T>を借りる

563 :名無しさんだよもん:02/04/17 20:59
以下の状況に最適なコンテナを教えてください。


クラス「Buffer」は、intを格納するコンテナをメンバ変数として持っています。

Buffer buf;
buf.Set([コンテナ]);

とすると、引数で渡されたコンテナ内のデータ(もちろんint)を、
メンバコンテナの最後尾に追加します。追加は最後尾にしか行われません。

「引数で渡すコンテナ」自体のデータ生成も、常に「最後尾にデータ追加」
という形で行われ、 Set() を行うときには、size() がだいたい2〜20
ぐらいになっています。 Set() が終わったら役目を終えて、
スコープアウトして破棄されます。
これをループで50〜200回ぐらい行って、メンバコンテナ内にデータを
溜め込んでいきます。

それで、 set() 呼び出しが一通り終わったら、

cout << buf;

として、メンバコンテナ内部に溜め込んだデータをすべて、入ってきた
順番どおりに出力します。

Buffer内部のコンテナと、引数で渡すときのコンテナは、それぞれ
何を使うべきでしょうか?

なお、取り扱うデータは、ホントにintです。「話を簡単にするために」
とかじゃなくて、実際にintを処理します。

564 :デフォルトの名無しさん:02/04/17 21:05
とりあえず、そういうときは、dequeでGO!
(20KほどReserveしたvectorでも可)

565 :デフォルトの名無しさん:02/04/17 21:06
vector<int>かなぁ?

566 :デフォルトの名無しさん:02/04/17 21:07
listかvectorか迷うところだけど、まあlistだろうね。
ランダムアクセスしないみたいだし、spliceが効きそうだし。

567 :デフォルトの名無しさん:02/04/17 21:14
intなデータに、ポインタを2つもつけるのは、
こう、いかがなものかと。

568 :デフォルトの名無しさん:02/04/17 21:20
実はただの配列が一番いいとかいう罠

569 :デフォルトの名無しさん:02/04/17 21:22
vectorで十分だろ。

570 :デフォルトの名無しさん:02/04/17 21:24
new int...は面倒臭いよ。
設計自体を変えるか、迷うんだったらとりあえずvector。
それかコンテナもテンプレートにしとけ。

571 :デフォルトの名無しさん:02/04/17 21:28
>>568
それだ!要素数は2〜20くらいとか書いてるし、多めに100くらい取っておけば問題なさげ(適当)

572 :デフォルトの名無しさん:02/04/17 21:29
std::for_eachとかでしつもんれす。

関数オブジェクトを渡していろんなコンテナをぐるぐる順次処理したいのですが、
関数オブジェクトの内部に配列とか、その、いろんなものを持たせておいて
最後に ResultT result(std::for_each(v.begin(), v.end(), FuncObj(parameters)).getresult());
みたいなことがやりたいのです。

で、通常for_eachは関数オブジェクトをコピーで受け取り、コピーで返すわけですが、
関数内部のデータのコピーをどう、保持してやるべきかと、悩んでます。

関数オブジェクト自身のコピーのコストがバカにならず、
pimplイディオム+boost::shared_ptrを使おうとおもっとります。

で、本題なんですが、
クラスのメンバにshared_ptrを持っているとき、コピーコンストラクタや代入演算子を
きちんと定義してやらないとまずいでしょうか?
それともデフォルトのコピーコンストラクタに任せちゃってもOKですか?


573 :572:02/04/17 21:31
いちおう、関数オブジェクトを参照型で渡せばなんとかなりそうな気配もするのですが、
これが一時オブジェクトだった場合に、最後にgetresult()する瞬間まで
一時オブジェクトが生きてるのかどうか、どっちだったか忘れてしまってます。

コンパイラによっては参照渡しのfor_eachはダメらしいので、
とりあえずコレはなしでおながいします。

574 :デフォルトの名無しさん:02/04/17 21:32
出来るかどうか知らんけど、FuncObj を auto_ptr<> で囲ってみるとか

575 :574:02/04/17 21:33
あぁ。よく考えたらダメっぽ。

576 :デフォルトの名無しさん:02/04/17 21:34
大丈夫じゃないかな。たぶん。
つうか、俺自身最近コピコンなんて書いてない...。

577 :デフォルトの名無しさん:02/04/17 21:41
一時オブジェクトはセミコロンまで生きてるんじゃないかな。
そうでないと普通に const string& 引数に渡した一時 string が心配。

578 :572:02/04/17 21:53
ありがとうです。
これで安心してぐるぐるやれます。

ついでに聞いてみますけど、boost(shared_ptr)を使わないでこの問題を解決する
としたら内部データは別に持っておいて、それへのポインタを関数オブジェクトに
持たせてやるしかないのでしょうか?


579 :名無しさんだよもん:02/04/17 22:07
うわ、いっぱいレスが…。でも、みんなバラバラですね。(^^;

配列は渡すときのサイズ指定とかが面倒だし、予定サイズを
もし超えた場合の対処が出来ないので、これはさすがに却下
させていただくとして…。

いままでdequeを使ったこと無かったんですが…こういう状況に合うような
モノだったんですかね。ちょっと勉強します。

listは、>>566>>567さんの書かれてるとおりのネタで悩んでました。
boostに単方向リストとかいうのがあるらしいと聞いたんで、
それならどうだろう…とかも。

結局、コピー追加をしても大してコストがでかくないから、vectorを
使うのが正解ですかね…?

ところで、>>570さんの、「new int...は面倒」と「コンテナも
テンプレートにしとけ」って、どういう意味ですか?
さっぱり分かりません。(T_T)

580 :570:02/04/17 22:25
template <template <class> class T>
class Buffer
{ // ...
ってこと。

581 :デフォルトの名無しさん:02/04/20 01:50
うおー!! なんでlistにはstableなsortがないんだー!!

名前と年齢を持つクラスをソートするとき、名前でソートしたあと、
年齢でソートした場合、同じ年齢の中では名前順がいいよね?

こういう場合、どうするのが一番スマートなんでしょう。自分で
stableなsortを実装するってのじゃ、STLを使う意味が半減するので…。


582 :デフォルトの名無しさん:02/04/20 02:27
>>581
> うおー!! なんでlistにはstableなsortがないんだー!!

STL以前に基本がなってないと思われ。

#include <list>
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>

using namespace std;

struct Person {
string name_;
int age_;
Person(string name, int age) : name_(name), age_(age) {}
bool operator<(const Person &other) {
return age_ == other.age_ ? name_ < other.name_ : age_ < other.age_;}
void out() {cout << name_ << ": " << age_ << endl;}
};

int main() {
list<Person> group;
group.push_back(Person("mona3", 3));
group.push_back(Person("mona0", 3));
group.push_back(Person("mona1", 15));
group.push_back(Person("mona2", 3));
for_each(group.begin(), group.end(), mem_fun_ref(&Person::out));
group.sort();
cout << "sorted." << endl;
for_each(group.begin(), group.end(), mem_fun_ref(&Person::out));
}


583 :デフォルトの名無しさん:02/04/20 02:52
>>581
あれ、list::sort って安定じゃなかったっけ?
あれってマージソートの変形版だし。

584 :デフォルトの名無しさん:02/04/20 02:52
#include <list>
#include <vector>
#include <algorithm>
#include <iterator>
#include <string>
#include <iostream>

template<typename T>
struct Dereference : std::unary_function<T &, T *> {
T *operator () (T &t) const { return &t; }
};

template<typename T>
こういうことじゃなくて?

struct ConstReference : std::unary_function<const T *, T> {
T operator () (const T *p) const { return *p; }
};

template<typename T>
struct DereferenceLess : std::binary_function<const T *, const T *, bool> {
bool operator () (const T *p1, const T *p2) const { return *p1 < *p2; }
};

class Person {
std::string name_;
int age_;
public:
Person(std::string name, int age) : name_(name), age_(age) {}
friend bool operator<(const Person &a, const Person &b) {
return a.age_ == b.age_ ? a.name_ < b.name_ : a.age_ < b.age_;
}
friend std::ostream &operator << (std::ostream &os, const Person &p) {
return os << p.name_ << ": " << p.age_ << std::endl;
}
};

int main()
{
std::list<Person> l;
std::vector<Person *> v;

l.push_back(Person("mona3", 3));
l.push_back(Person("mona0", 5));
l.push_back(Person("mona1", 15));
l.push_back(Person("mona2", 2));

v.reserve(l.size());
std::transform(l.begin(), l.end(), std::back_inserter(v), Dereference<Person>());
std::stable_sort(v.begin(), v.end(), DereferenceLess<Person>());
std::transform(v.begin(), v.end(), std::ostream_iterator<Person>(std::cout), ConstReference<Person>());

return 0;
}



585 :584:02/04/20 02:53
listの要素をstable_sortしたいんじゃねえの?

と書こうとして行がずれた...宇津志。


586 :581:02/04/20 03:20
ありがと!!

>>582 operator < で複数の条件を調べればよかったのか…先の例では
これでOKっすね。

>>583 手元にSTLの規格書がないのでなんとも言えませんが、listのsortは
マージソートで、stableだと保証されているものなのでしょうか?

>>584 listの各要素へのポインタをvectorで保持する? 手元の本に
transformアルゴリズムの詳しい説明がないので、別の本買ってきます…。


本当はreaddir()で取得したファイルの情報をソートしたかったんですよ。
lsを作りたいということで。それで名前でソートしたり日付でソートしたり、
ディレクトリを先頭に集めたり…。

ファイルの情報はクラスに格納してしてlistでつなげていたのですが、
名前でソートしたあとにディレクトリを先頭に集めると、名前順が崩れるんですよ。
名前ソート/ディレクトリソートは単独では正常に動作します。

>>582の解法が良さそうなんですが、operator < の中身が肥大化しそう…。
先に>>584を理解するのが先決かな。

587 :よる:02/04/20 03:34
載させていただきます
http://www.h4.dion.ne.jp/~k.seed/

588 :デフォルトの名無しさん:02/04/20 16:22
operator < を定義して std::setに突っ込むだけでよかったみたいだな。


589 :デフォルトの名無しさん:02/04/23 00:07
あげ

590 :デフォルトの名無しさん:02/04/25 20:11
age



591 :デフォルトの名無しさん:02/04/25 20:17
>>588 そうなの?

592 :デフォルトの名無しさん:02/04/26 00:33
boost::lexical_castだけど、設計間違ってるとしか思えないんだが。
あれじゃぁstd::stringに変換出来るが、std::wstringに変換出来ないじゃん。
あの宣言じゃ特殊化も出来ないし

593 :デフォルトの名無しさん:02/04/26 01:08
それよりVC6でboost::tokenizerがまともにコンパイルできないのが悲しい..
TCHAR(char/wchar_t切り替え)ベースでtokenizerを使うにはどうしたらいいもんかね?

locale絡みの問題は、とりあえずおいといて。


594 :デフォルトの名無しさん:02/04/27 03:27
結局つくっちまいますた。
おいらの車輪は.....

vcのおまけのchar_traitsが使えるかどうか検討中。


595 :デフォルトの名無しさん:02/04/27 03:56
MBCSの都合を全然考えてないchar_taitsに乾杯☆

596 :デフォルトの名無しさん:02/04/27 08:28
>>595
問題あるならchar_traits位自分で書けよ

597 :デフォルトの名無しさん:02/04/27 13:30
motironnkaita

598 :デフォルトの名無しさん:02/05/03 16:51
char_traitsのべたな実装のままだとだめやんけ。
あきらめてboost::tokenizer互換で行こうかと思ったが
体力ないので保留。


599 :デフォルトの名無しさん:02/05/06 00:19
mapの要素にvectorを指定することは出来ないのでしょうか?

#include <vector>
#include <map>
using namespace std;

int main()
{
 map<int, vector<int>> aMap;
 // ....
}

みたいな事をするとコンパイルエラーになっちゃうのですが…


600 :デフォルトの名無しさん:02/05/06 00:22
VC?

601 :デフォルトの名無しさん:02/05/06 00:22
(*´Д`)
 マァ・・・

602 :デフォルトの名無しさん:02/05/06 00:22
>>599
ありがち。 >> と書くと operator>>() と勘違いされるから > > と書きましょう。

603 :601:02/05/06 00:23
いやああぁあ!!
たった3文字に先を越された!!
コンチクショウ!!

604 :599:02/05/06 01:29
>>602
> >でうまく行きました。ありがとうございました。
ちなみにBCC5.5.1でした。


605 :デフォルトの名無しさん:02/05/06 03:32
>>596
char_traitsだけ書き換えてもMBCS対応にはできないと思うが・・
basic_string::rfind()あたりで。

606 :デフォルトの名無しさん:02/05/06 03:45
auto_ptr
list
vector
map

以上を使用するときに必要なヘッダーファイル(#include <***>の***部分)を教えて


607 :デフォルトの名無しさん:02/05/06 03:46
ん・・・
素直に
auto_ptr #include<auto_ptr>
list #include<list>
vector #include<vector>
map #include<map>
でいいのかな?


608 :デフォルトの名無しさん:02/05/06 03:47
>>606
全てのヘッダーを読み込めばいいだろうがボケ!

609 :デフォルトの名無しさん:02/05/06 03:52
>>606
auto_prt -> #include<memory>

610 :デフォルトの名無しさん:02/05/06 10:31
つーか、日本語とか扱うなら素直にwchar_t使え的。
でも、結局サロゲートペアとか使われると破綻する?

611 :593:02/05/06 12:45
>>610
おいら宛の書き込みかな?
ターゲットがwin32だからwchar_tで十分だね。

MBCS/Unicodeどっちでも通るように作っておきたい
ってのが、わがままなんだろうな。


612 :デフォルトの名無しさん:02/05/06 15:17
ていうかね、そもそもboost::tokenizerなんて使い捨てプログラムとか
プロトタイプにしか使わないからどーでもよさげ。

613 :デフォルトの名無しさん:02/05/12 15:04
#include <iterator>

class C
{
  int* beg;
  int* end;
public:
  size_t dis() const{
    return std::distance(beg, end) * 2;
  }
};

int main(){ return 0; }

bccだとコンパイルできない罠

614 :デフォルトの名無しさん:02/05/12 23:10
>>613
Borland-C++5.6だと通る罠。

615 :デフォルトの名無しさん:02/05/12 23:43
なんでsize_tなんだ?
iterator_traits<T>::distance_typeじゃないのか?

616 :デフォルトの名無しさん:02/05/13 01:36
>614
あれ、5.6なんてあるのですか?5.51では通りませんですた

>615
そこは突っ込んで欲しくなかったのに。傷つきますた。おかげで傷ものです。

617 :デフォルトの名無しさん:02/05/13 02:00
>>616
BC++5.6は、BCB6の付属品ですよっ。BCB6のコンパイラエンジンと同じなのね。
Rogue WaveからSTLPortに変わったので、コンパイルできるんじゃないですか。

・・・・と思って、Rogue Waveの実装を使う、_USE_OLD_RW_STLマクロを定義して
コンパイルしても、通ってしまいました。5.5.1のバグなんでしょうか。

618 :デフォルトの名無しさん:02/05/13 02:09
実装依存なだけでバグじゃないよ。
バージョン刷新の時に仕様が変わったんでしょ

619 :デフォルトの名無しさん:02/05/14 03:01
age

620 :デフォルトの名無しさん:02/05/14 03:42
>617
確認サンクスコ。
フリーの方も次で修正されてると良いんだけど。

621 :デフォルトの名無しさん:02/05/14 07:20
>>620
バグでも無いのに修正って?
そんな実装依存に頼るんじゃ、わざわざstd::distanceを使う意味がないと思うが

622 :デフォルトの名無しさん:02/05/14 12:08
これならBC++5.5.1でも通るでしょ。

template <class T>
class C
{
T* beg;
T* end;
public:
typename std::iterator_traits<T>::difference_type dis() const {
return std::distance(beg, end) * 2;
}
};

int main()
{
return 0;
}

623 :デフォルトの名無しさん:02/05/14 12:49
>>616
傷つかんでよろしい。>>615 も間違ってるから。

624 :デフォルトの名無しさん:02/05/14 15:39
>622
通らないんじゃない?
mainに C<int> n; って付け足してみ。

625 :デフォルトの名無しさん:02/05/14 15:49
>>624
本当だ。通らない。なぜだーーーーー

626 :デフォルトの名無しさん:02/05/14 16:10
valarray に独自メモリ管理機能を使いたいんだけど、
vector や list などのコンテナみたいに allocator の指定ができないので、
独自に valarray ライクなクラスを作らにゃいかんのだろうか。


627 :デフォルトの名無しさん:02/05/14 16:53
>>625
なぜって、iterator_traits<T*> にしなきゃ。

628 :デフォルトの名無しさん:02/05/14 17:07
>>627
サンクス!!
ポインタの減算だから、*をつけなきゃいけないんですね。

629 :デフォルトの名無しさん:02/05/14 18:51
>627-628
ところが、
 C<int> c;
 c.dis();
って感じでメンバを呼び出すと、また通らなくなる罠。

630 :デフォルトの名無しさん:02/05/14 20:00
ptrdiff_t dis() const {
return std::distance(beg, end) * 2;
}


631 :デフォルトの名無しさん:02/05/14 20:10
>>629
ん?BC++5.6だと通るぞ。また実装依存か。

632 :デフォルトの名無しさん:02/05/14 20:14
MSDNに「一部の特殊化がサポートされてないとptrdiff_tが使われる」と書いてあるので、
BCC5.5の機能が少ないんでしょ

633 :デフォルトの名無しさん:02/05/14 20:18
javaのgenericsってなんか問題あります?
今からC++のSTLを覚えるよりは、javaのgenericsを覚えた方が
一般的に得だと思うので。

634 :デフォルトの名無しさん:02/05/14 20:29
STLとgenerics・・・
比較する物が違うぞ

635 :デフォルトの名無しさん:02/05/14 20:39
http://objectclub.esm.co.jp/JavaGenerics/
genericsには反復子ってあるの?

636 :613:02/05/14 21:19
BCC55の修正項目発見しますた。
include/rw/iterator.hの146行目あたりに付け加えると吉。
template <class T> struct iterator_traits<T* const>
{
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef const T* pointer;
typedef const T& reference;
typedef random_access_iterator_tag iterator_category;
};

これで通るようになります。
#include <iterator>
#include <iostream>

template <class ITE> class C
{
ITE beg;
ITE end;
public:
std::iterator_traits<ITE>::difference_type dis() const{
return std::distance(beg, end);
}
C(ITE b, ITE e) : beg(b), end(e){ }
};

int main()
{
int n[] = { 0, 1, 2, 3, 4, 5};
C<int*> c(n, n + 3);
std::cout << c.dis() << std::endl;
return 0;
}


637 :デフォルトの名無しさん:02/05/14 21:56
>>636
BCC はまったく知らないので、的外れだったらすまんが、
template <class T> struct iterator_traits<T* const>
というのは、あまり見かけたことがない。ふつうは、
template <class T> struct iterator_traits<T*>

template <class T> struct iterator_traits<const T*>
だけあれば充分だったと思うが。

638 :636:02/05/14 22:19
>637
borland系はいるのかも。STLportの方にもこんなのが。

# if defined (__BORLANDC__)

template <class _Tp>

struct iterator_traits<_Tp* const> {

//...
};

# endif

639 :デフォルトの名無しさん:02/05/14 22:22
なんか変な改行が入りまくったけど、( ´3`)キニシナイ

640 :デフォルトの名無しさん:02/05/14 22:25
>>638
そうでしたか。的外れスマソ

641 :デフォルトの名無しさん:02/05/14 22:46
>>636
なるほど。しかし、この修正を必要とするほどBC++5.5.1を使い込んでいるヤシ
はどれくらいいるのだろう?俺はもっぱら勉強用。

642 :デフォルトの名無しさん:02/05/15 06:19
自作Classをsetやmapで使いたい場合==と<をオーバーライドするんだけど
この<の設計がむずくないですか?
ヘタに作るとinsertでとりこぼす。
setに7000個入れたら6950個蹴られた。(笑
頭に来て↓にしたらOKになった。みなさんはどうしてる?
bool operator<( const A& other) const
{
return this < &other;
};

643 :デフォルトの名無しさん:02/05/15 06:52
>>642
とりあえず、operator < の意味を知れ。
「等値」「等価」あたりがキーワードと思われ。

644 :デフォルトの名無しさん:02/05/15 07:36
>>643
いや、理屈はわかるよ、
でもね、実際組むとなると難しいところなのよ。
operator<を組まないととりこぼす、
組むとなると複雑なロジックになり
手間はかかるし処理時間もかかる。
例えばベクトルをメンバにもつクラスだとすると
何をもってして等、不等とするのか。
大きさにするのか、向きにするのか、両方を参照して決めるのか等々。
そんなのが何個もメンバとしてもってたりすると大変なのよ。
でもsetの機能は享受したい、でもmultsetでは足りないとか。

645 :644:02/05/15 07:39
そして>>642の方法をとると
「とりあえず一意のユニークな値だよ。
だからsetさん蹴らないでね。
でも縦列は問わないよ。
だからソートする際は気にしなくていいよ。」
ってな意味になる訳よ。

646 :デフォルトの名無しさん:02/05/15 08:01
単純に「全部入れたい」だけなら>>642でいいんでないの?

しかし、別オブジェクトであっても等値な場合があるなら、
> 例えばベクトルをメンバにもつクラスだとすると
> 何をもってして等、不等とするのか。
この辺は自明だと思うけど。向きに意味を持たせないsetを作りたいなら
大きさだけで比較すればよいし、そうでないならそれなりの比較演算を
すればよいってだけで。

647 :デフォルトの名無しさん:02/05/15 09:46
順序付けられない値をSetやMapに入れて
機能の享受も糞も無いと思うんだけど・・
データ設計からやり直しがよいかと。

648 :デフォルトの名無しさん:02/05/15 13:57
>>647
hash_set, hash_map を使いたいってことじゃないかな?
SGI版や STLport版を使わない理由が、よく判らないけど。

649 :デフォルトの名無しさん:02/05/15 17:29
>>648
どちらにせよ唯一性をアドレスでしか示せないなら無意味じゃないの?
アドレスわかってんなら検索する必要など無い・・。
唯一性を示すキーと対応付けてるんならこんなことで悩まないでしょ?

650 :デフォルトの名無しさん:02/05/15 22:06
>>644
>例えばベクトルをメンバにもつクラスだとすると
>何をもってして等、不等とするのか。

lexicographical_compareで一発

でもそんな必要ないならアドレス比較でいいんじゃない?
hash_set にするっつっても、ハッシュ値出すのもしんどそうだけど。

651 :デフォルトの名無しさん:02/05/16 00:16
struct hoge {
string s1;
string s2;
};

vector<hoge> hoges;

のとき、hogesをファイルに読み書きするには
どうするのが一番かっこいいんですか?

652 :643:02/05/16 00:39
>>644
理屈も分かってなさそうに見えるよ。
operator < は評価の順序付けのために定義するもんだ。
順序とは違う「setの機能が享受したい」なんて意味を operator < に
持たせるのは激しく筋違い。
アドレスの比較を使って set に入れたいなら
そういう意味の比較関数オブジェクトを set のテンプレートパラメーターに渡せ。

653 :デフォルトの名無しさん:02/05/16 00:49
>>651
画面に表示して手書き

654 :デフォルトの名無しさん:02/05/16 00:49
>>651
こんなのでどう。

template<typename T>
basic_ostream<T>& operator<<(basic_ostream<T>& out, const hoge& h)
{
  return out << h.s1 << '\n' << h.s2;
}

ofstream out("ファイル名", ios_base::out);
copy(hoges.begin(), hoges.end(), ostream_iterator<hoge,char>(out, '\n'));

655 :651:02/05/16 00:56
>>654
イイ!なんかすごくかっこよさそうです。
早速実験してみます。

656 :デフォルトの名無しさん:02/05/16 01:25
>>653
WaRoTa

657 :651:02/05/16 01:29
#include <vector>
#include <string>
#include <ostream>
#include <istream>
#include <fstream>
#include <iterator>
using namespace std;

struct hoge {
string s1;
string s2;
};

template<typename T>
basic_ostream<T>& operator<<(basic_ostream<T>& out, const hoge& h)
{
return out << h.s1 << '\n' << h.s2;
}

int main()
{
vector<hoge> hoges;
hoge h;
h.s1 = "111";
h.s2 = "aaa";

ofstream out("data", ios_base::out);

copy(hoges.begin(), hoges.end(),
ostream_iterator<hoge,char>(out, '\n'));  <−エラー

return 0;
}

error C2665: 'ostream_iterator<struct hoge,char,struct std::char_traits<char> >::ostream_iterator<struct hoge,char,struct std::char_traits<char> >' : 2 のオーバーロードは 2 番目の引数を 'const char' から要
求の型に変換できません。(新しい機能 ; ヘルプを参照)

すいません。コンパオルエラーでたんですが、解決方法がわかんないです。
だってエラーが長いんだもん

658 :デフォルトの名無しさん:02/05/16 01:39
>>657 "\n"

659 :デフォルトの名無しさん:02/05/16 02:13
ありがといございます。コンパイルできました。
それでファイルからの読み取りを以下のように書いてかんせいしました。ヤタ

template<typename T>
basic_istream<T>& operator>>(basic_istream<T>& in, hoge& h)
{
return in >> h.s1 >> h.s2;
}

ifstream in("data", ios_base::in);

vector<hoge> hoges;
hoge h;
while( in >> h )
hoges.push_back(h);



660 :デフォルトの名無しさん:02/05/16 02:26
>>659
hoges.assign( istream_iterator<hoge>( ifstream("data") ) , istream_iterator<hoge>() );


661 :デフォルトの名無しさん:02/05/16 13:23
>>652
同意。

というか 642 がいう「set の機能」って何なんだ?

662 :デフォルトの名無しさん:02/05/16 23:42
質問。

class Foo {
public:
int getVal() const { return foo; }
pravate:
int foo;
};

っといういうクラスがあった場合
fooの値でremove_ifを行いたいのですが、その書式がわかりません。
たとえば、fooの値が100以下であれば削除としたいのですが。

list<Foo> l;
remove_if(l.begin(), l.end(), /* ココが? */);

663 :デフォルトの名無しさん:02/05/16 23:51
>>662
remove_if(l.begin(), l.end(), bind2nd(greater_equal<int>(), 100));

664 :デフォルトの名無しさん:02/05/16 23:52
remove_if(l.begin(), l.end(), bind2nd(less_equal<int>(), 100));
だった。逝ってきます・・・・・

665 :デフォルトの名無しさん:02/05/16 23:53
>663
それではfooの値・getVal()を考慮しないんじゃないでしょうか?

666 :デフォルトの名無しさん:02/05/16 23:57
>>662,665
おい、listのときはメンバにあるほうのバージョンを使え。
l.remove_if( pred );
だ。

667 :デフォルトの名無しさん:02/05/17 00:43
>>662
Foo専用の叙述関数を書く。プログラミング言語C++第3版§18.4.2.1参照。

class Foo {
public:
int getVal() const { return foo; }
private:
int foo;
};

class Foo_le : public unary_function<Foo, bool> {
int i;
public:
explicit Foo_le(const int &ii) : i(ii) {}
bool operator()(const Foo &f) const { return f.getVal() < i; }
};

int main()
{
list<Foo> l;
l.remove_if(Foo_le(100));
}

668 :デフォルトの名無しさん:02/05/17 01:02
less_equalは使えないのか?

669 :デフォルトの名無しさん:02/05/17 06:13
STLPortなんですけど、
class Foo
{
vector< int > hoge;
};
----------------------------
Foo foo;
foo.hoge.push_back( 10 );
foo.hoge.push_back( 20 );
foo.hoge.push_back( 30 );

set< Foo > setFoo;
setFoo.insert( foo);

int numhoge = setFoo.begin()->hoge.size();

とやると何故かnumhogeの値が1になってしまいます。
なぜなんでしょうか?


670 :デフォルトの名無しさん:02/05/17 06:22
ならないよ

671 :デフォルトの名無しさん:02/05/17 06:40
気のせいだ

672 :669:02/05/17 06:56
でも実際なるんですよ。
setFooにfooを複数個入れて
すぐデバックアウトプットしてみると
全部サイズが1で中身も変になってるんです。

673 :デフォルトの名無しさん:02/05/17 07:02
operator<は適切?

674 :669:02/05/17 07:21
すいません。hogeはset< DWORD >の間違いでした。
class Foo
{
set< DWORD > hoge;
};

>>673
こんな感じです。
bool operator<( const Foo& opp) const
{
set< DWORD >::const_iterator ihoge, iOpphoge;
for(ihoge = hoge.begin(), iOpphoge= opp.hoge.begin();
ihoge != hoge.end() || iOpphoge!= opp.hoge.end();
ihoge++, iOpphoge++)
{
if( ihoge == hoge.end() &&
iOpphoge != opp.hoge.end())return true;
else
if( ihoge != hoge.end() &&
iOpphoge == opp.hoge.end())return false;

if( *ihoge < *iOpphoge)return true;
else
if( *ihoge > *iOpphoge)return false;
}


675 :デフォルトの名無しさん:02/05/17 08:01
class Foo
{
public:
 std::set<DWORD> hoge;
 bool operator<(const Foo& rhs) const
 {
  std::set<DWORD>::const_iterator iter1, end1;
  std::set<DWORD>::const_iterator iter2, end2;

  iter1 = hoge.begin();
  iter2 = rhs.hoge.begin();

  end1 = hoge.end();
  end2 = rhs.hoge.end();

  for (;iter1 != end1 || iter2 != end2; iter1++, iter2++) {
   DWORD a = *iter1;
   if (iter1 == end1 && iter2 != end2)
    return true;
   else if (iter1 != end1 && iter2 == end2)
    return false;

   if (*iter1 < *iter2)
    return true;
   else if (*iter1 > *iter2)
    return false;
  }
  return false;
 }
};

Foo foo;
foo.hoge.insert(10);
foo.hoge.insert(20);
foo.hoge.insert(30);

std::set<Foo> setFoo;
setFoo.insert(foo);
setFoo.insert(foo);

setFoo.size() => 1
setFoo.begin()->hoge.size() => 3

(俺には)見づらかったのでなおして試したけど、正常だが?

676 :デフォルトの名無しさん:02/05/17 08:02
>DWORD a = *iter1;
これは気にしないでくれ

677 :669:02/05/17 08:30
>>675
ぐあーわかりましたぁぁ。
デバック出力用に
ストリームにhogeの値を出力するような
コードを書いていたんですが、
その中に ; が1個紛れ込んでました。
そのせいでヘンな値が出力されていたようです。
つーか真できます。ありがとうございました。

678 :デフォルトの名無しさん:02/05/17 08:36
心おきなく真でくれ

679 :デフォルトの名無しさん:02/05/17 22:39
stringの書式化はどうすればいいんでしょか。


680 :デフォルトの名無しさん:02/05/17 23:45
>>679
string sに文字列が入っているとして
ostringstream os(s);
とすれば、os.str()から返される値がsを反映したものとなる。
同様に、
istringstream is(s);
とすれば、sの内容から入力できる。
C++標準ライブラリ、ASCII、§13.1.1.参照

681 :679:02/05/18 02:28
>>680
できました。ありがとうございます。


682 :デフォルトの名無しさん:02/05/18 12:43
vectorコンテナをサーチして
ある要素が何番目に位置しているか知るための
関数は用意されてますか?

683 :デフォルトの名無しさん:02/05/18 12:50
std::distance

684 :デフォルトの名無しさん:02/05/18 13:09
>>682
std::find

685 :デフォルトの名無しさん:02/05/18 13:39
>>684
検索が非常に多いことが分かってるなら事前に sort させてしまって、検索には
binary_search を使うと良いかも。

686 :デフォルトの名無しさん:02/05/18 14:12
binary_searchの戻り値は何故かboolです。
equal_rangeをどうぞ

687 :デフォルトの名無しさん:02/05/18 14:41
template <typename T> CTestStr : public T
{
public:
CTestStr(){};virtual ~CTestStr(){};
};

void Test
{
CTestStr<std::wstring> ss;
(std::wstring)ss = _T("aasd");
ss.length();// 0
}

としてるんですが、
ss.length()が0で
ssが不適切なPtrですとデバックウィンドウに出ます。(VC.NET)
UNICODEプロジェクトにしたし、ヘッダーもIncludeしたはずなのですが
なぜなのでしょうか。追記:
CTestStr<std::string> ss; だとうまくPtrは取得できているみたいなんです。


688 :687:02/05/18 14:44
× template <typename T> CTestStr : public T
○ template <typename T> class CTestStr : public T


689 :デフォルトの名無しさん:02/05/18 14:47
static_cast<std::wstring&>(ss) = _T("aasd");

それから、stringを継承するのはよくない。
いくら子クラスでデストラクタをvirtualにしたところで、
親がvirtualで無いから無意味

690 :687:02/05/18 15:18
>>689
動きました。感謝!!
string,wstring,... 継承したいのはMFCのCStringとSTLの共通クラス&
UNICODE考慮したStringを作りたい(進行|上半分の皮ができたつもり)からなんです。
誰か手伝ってくれる人はいないよね...(w。


691 :682:02/05/18 15:45
ありがとうございます。
>>683
distanceで組んでみたんですがうまくいきませんでした。
distanceはfirestからlastまでの差分を返すんだと思いますが
これで検索を行う場合、firestにはコンテナの最初のイテレータ
lastには捜したい値を示す別のコンテナのイテレータになってしまうと
思うんです。これであってますか?

>>684-686
インデックスが知りたいんですが
返されるイテレータを使って知る方法があるんでしょうか?

692 :デフォルトの名無しさん:02/05/18 17:28
find で返されるイテレータを distance にかければ判るだろ。
vector<int> v;
vector<int>::iterator i = find(v.begin(), v.end(), 10);
if(i != v.end()){
 int index = distance(i, v.begin());
}
「組み合わせる」という言葉を知らないか?

693 :692:02/05/18 17:29
うぉっと。distanceの引数間違い。正しくは distance(v.begin(), i)

694 :682:02/05/18 18:37
>>692
ありがとうございました。勉強になりました。
ですがそれでは2回走査することになり
効率的ではないですね。
普通に順次検索した方が良さそうですね。
vectorにそれ系のメソッドが無いのも
そういう理由かもしれませんね。

695 :694:02/05/18 18:51
vector なら distance は引き算1回で実装されると思うけど、どうよ。

696 :682:02/05/18 19:01
>>695
そうみたいです。
試しに実装してみたら、5倍近速くなりました。
びっくりです。
マジありがとうございました。

697 :デフォルトの名無しさん:02/05/18 19:28
やりとりがワラエタ

698 :デフォルトの名無しさん:02/05/18 19:36
>>686
binary_searchの替わりは、lower_boundだと思う。

699 :デフォルトの名無しさん:02/05/20 07:20
npos
は何を指しているのでしょうか?

700 :デフォルトの名無しさん:02/05/20 07:21
存在しない位置

701 :699:02/05/20 07:33
>>700
std::string s;
s = "tzest";
char t = 'z';
s.find_last_of(t,npos);

find_last_ofのデフォルトの引数見たら、nposになってたんですけど
nposから検索できないような気がするのですが、なぜなんでしょう。


702 :デフォルトの名無しさん:02/05/20 09:58
mapは便利!!
STLは神!!

703 :デフォルトの名無しさん:02/05/20 10:52
>701
s.find_last_of(t)でいいじゃないの?
オレのとこでは動くけど? VC6SP5

704 :デフォルトの名無しさん:02/05/20 11:33
>>703
nposをIndexに入れても動くようにたぶん実装されてるみたいですね。
STLを信用してスマートなs.find_last_of(t)でいくことにします。


705 :デフォルトの名無しさん:02/05/20 17:12
std::localeのUNICODEバージョンのstd::wlocaleって
VCにはないんだけど、これってVCの仕様なの?STLの仕様?
でもなんでないん?


706 :デフォルトの名無しさん:02/05/20 21:33
localeのUNICODEバージョンなんかあるか。ロケールは文字コードに関係なく共通だ。

collate<wchar_t>, ctype<wchar_t>, money_get<wchar_t>, money_put<wchar_t>, num_get<wchar_t>, num_put<wchar_t>, time_get<wchar_t>, time_put<wchar_t>

どれても入り用なものをどうぞ。

707 :705:02/05/21 01:26
>>706
>UNICODEバージョンなんかあるか
その理由を聞いているんだが。

localeコンストラクタの
  locale::locale(const char *s)

これってwchat_t型があってもよさげだけど。
この引数は「ASCI文字しか指定しない」ってだけだからなのか?


708 :デフォルトの名無しさん:02/05/21 07:35
>>707
あぁ、それか・・・
たぶんそんなことじゃないかね。
basic_fstream のコンストラクタ引数だって、テンプレートの charT じゃなくて const char* になってるし。

709 :デフォルトの名無しさん:02/05/21 13:13
>>708
チトちゃんとした例を挙げるのが遅かった。失礼。

>basic_fstream
…あ、ホントだ。こっちは知らなかった。情報サンクスコ。

ここらへんもwchar_tに配慮してくれればコーディング
する側としては自由度が広がってありがたいのだが…。
なんとも歯切れの悪い納得になってしまった。
改良(or 納得のいく理由)を求む!>>ANSI or STL開発者


710 :デフォルトの名無しさん:02/05/21 21:17
>>709
予想→「あ、忘れてました、すんません」
・・・んなわけないか。
でも fopen に対して wfopen てあったっけ?
きっと、ファイルシステムがワイド文字を格納できない可能性を考えて、保証できそうな最低ラインを選んだとかじゃなかろーか。

711 :705:02/05/22 15:04
>>710
レスサンクスです。

>予想→「あ、忘れてました、すんません」
俺もそうであることを願いたい。
確か叙述関数を指定するcopy_ifも抜け落ちた
と言う話もあるし…。

でもlocaleもbasic_fstreamも構造を見ると
単なる間違いと言うよりは明示的にそのように
したとしか思えないような作りになってるし。
まぁ、俺らの様な厨どもには理解できない理由
があると思わ。

>wfopen てあったっけ?
う…VC以外ではUNICODE使ったことないからANSI
に規定されてるかどうか確認してない…。
スンマソン…。


712 :デフォルトの名無しさん:02/05/22 17:07
>>711
VC++のヘルプ見る限りでは_wfopenはANSI互換じゃないようだが。

713 :デフォルトの名無しさん:02/05/22 17:40
>>711
_(アンダーバー)ではじまる物は全部(ほとんど?)
VC++のみの機能。
ただ、open()はANSI規格だけど(だったよね?)
VCではANSI互換にはなってないようなので
_open()になってる。実際はVCでopen()、wfopen()
で使っても特に問題ないんだけど。なんでだろぉ〜…。
なんで_wfopen()しかなくてもANSIで規定されてないか
どうかは不明。

…なんかSTLから少し外れてきたような…スマンコ。


714 :デフォルトの名無しさん:02/05/22 18:47
>>713
openはANSIじゃないだろ。
POSIXにはあるが。

715 :713:02/05/22 18:57
>>714
そうだったか…。
適当なことを言ってしまった。
スマン…。


716 :デフォルトの名無しさん:02/05/23 11:40
>>714
UNIX でも open() はたいてい weak symbol になってるよね。

717 :デフォルトの名無しさん:02/05/25 17:30
size_typeってintへ変換できることは保証されてる?

718 :デフォルトの名無しさん:02/05/25 17:59
intじゃなくてsize_tへの暗黙の変換が存在することが保証されている

719 :デフォルトの名無しさん:02/05/25 18:16
なるほどどうも、じゃキャスト付けといたほうがいいか

720 :デフォルトの名無しさん:02/05/25 18:23
おおぼけ、比較以外は必要なかった

721 :デフォルトの名無しさん:02/05/25 18:55
size_tはintへの変換があるから問題ないんじゃないのか?

722 :デフォルトの名無しさん:02/05/25 19:57
size_t は unsigned long かもしれなくて long と int の違う処理系があるかもしれないから、付けといた方がいいんじゃないの?
あぁでもエラーにはならんか。

723 :デフォルトの名無しさん:02/05/27 16:45
basic_stringのバッファの生ポインタが欲しいのですが、
std::basic_string<unsigned char*> s;
_mbsrev(const_cast<unsigned char*>(s.data()));
とするのはまずいですか?
const unsigned char* ならとれるんですが,unsigned char*を返すメンバ関数が
見あたらないんです。
バッファを別に確保してもできないはこともないですが気になったので聞いてみました。


724 :デフォルトの名無しさん:02/05/27 17:04
>>723
だめ。
一度別のバッファにコピーして処理した後にbasic_stringに戻す

725 :723:02/05/27 17:49
>>724
安全を考えてそうすることにします。
ありがとう。

726 :デフォルトの名無しさん:02/05/27 20:04
std::vector<unsigned char>を使わない特別な理由でもあるのか?
std::vector<unsigned char>を使わない特別な理由でもあるのか?
std::vector<unsigned char>を使わない特別な理由でもあるのか?


727 :デフォルトの名無しさん:02/05/27 21:24
>>723
at(0) ではダメですか?非constな参照を返してくれますが。

728 :デフォルトの名無しさん:02/05/27 21:39
>>727
お前のプログラムを違う環境でコンパイルして動かないとき
よく「コンパイラのバグです」
とか言い訳してるだろ。


729 :デフォルトの名無しさん:02/05/27 21:44
>>728
いや、案外>>727でいいのかもしれん
>制御シーケンスの位置 pos の要素を指す参照を返す
シーケンス中の参照が変えることが保証されてるっぽい。

って、メモリ上で領域が連続している保証があるのってvectorだけだったっけ?
・・・

730 :デフォルトの名無しさん:02/05/27 21:48
>>729
OSのバグですとか、STLのバグですとか、ライブラリのバグです
っていいわけ得意だろ。


731 :デフォルトの名無しさん:02/05/27 21:49
ついでに、「よくわかんないけど戻したら動いた」
が得意だろ。



732 :729:02/05/27 21:56
>>730
いや、漏れはコピーの参照が帰える可能性が書かれていないので、
シーケンス中の参照が帰ってくることが保証されてるんじゃないのか
って言っただけなのだが。

733 :デフォルトの名無しさん:02/05/27 22:16
書いてないことは保証されていないぞ、伸吾君。

734 :デフォルトの名無しさん:02/05/27 22:35
final draft によると、at(pos) は operator[](pos) を返し、operator[](pos) は data()[pos] を返すそーです。
ここで const が外れるところが謎な定義になってますが、data() の戻り値は変更してはいけないそーなので、厳密に読むと無理っつぅことで。
data() の戻り値がメモリ上で連続してるのは保証されてるので、そっちは大丈夫ですが。

735 :デフォルトの名無しさん:02/05/29 17:59
教えてくだされぇ
本日VC7にてSTLPort入れました
が、
<cmath>、<ctime>系のヘッダを#includeしても、
std::sqrtなどが使用できません。

> C2039: 'sqrt' : '_STL' のメンバではありません。

とのことですが、なにぶんSTLPortのヘッダは複雑で一朝一夕には原因が究明できません。
どなたか解決法をご存知の方教えてくだされ。

736 :729:02/05/29 18:06
stl_user_config.hに
#define _STLP_DO_IMPORT_CSTD_FUNCTIONS 1
を追加

737 :デフォルトの名無しさん:02/05/29 18:06
げ、消し忘れた

738 :デフォルトの名無しさん:02/05/29 18:45
ああ、まだ上には上が痛んだな(´Д`)
お金貯めてEffective C++買おう

739 :デフォルトの名無しさん:02/05/29 18:47
>>736
助かりました!
無事コンパイルできました。

ところで、std::min<int>やmax<int>の戻り値がintじゃないのはなぜでしょうか?
警告イパーイヽ(゜∀。)ノアヒャ

あと、coutの出力先を変更するにはどのような方法があるでしょうか。
今までは
freopen( "hoge", "a+"), stdout );
して書き換えていたのですが、
STLPortでは見事に撃沈してしまいました(;; )

740 :739:02/05/29 18:49
追記
現状は
#define __STL_NO_SGI_IOSTREAMS 1
して逃げているのですが、
出来ればこの機会に正しい方法を知りたいと思います。
よろしくお願いします。

741 :デフォルトの名無しさん:02/05/29 20:25
>>740
ofstream fout("hoge.txt");
cout=fout;

ウソ言ってたらゴメン。


742 :デフォルトの名無しさん:02/05/29 20:59
ofstream ofs("hoge");
cout.rdbuf(ofs.rdbuf());
かな?

743 :デフォルトの名無しさん:02/05/29 21:16
coutはofstreamではなくostreamなので、rdbuf()があるかどうかは実装依存です

744 :デフォルトの名無しさん:02/05/29 23:43
質問させてください。
自前のiteratorを以下のように実装しました。

***ここから1***
class aIterator; // predeclaration
class bIterator; // predeclaration
class aConstIterator; // predeclaration
class bConstIterator; // predeclaration
class aIterator : public iterator_traits<list<a>::iterator> { bIterator b; 〜; };
class bIterator : public iterator_traits<list<b>::iterator> { aIterator a; 〜; };
class aConstIterator : public iterator_traits<list<a>::const_iterator> { bConstIterator b; 〜; };
class bConstIterator : public iterator_traits<list<b>::const_iterator> { aConstIterator a; 〜; };
***ここまで1***

これは問題なくコンパイルできます。
それでiteratorとconst_iteratorの定義でかなりかぶる『〜』の部分を
templateを使って省略しようと思い以下のようにしました。

***ここから2***
template<typename T,typename U>
aIteratorBase : public itetaror_traits<T> { U b; 〜; };
template<typename T,typename U>
bIteratorBase : public itetaror_traits<T> { U a; 〜; };

typedef aIteratorBase<list<a>::iterator,bIterator> aIterator; // (*1)
typedef bIteratorBase<list<b>::iterator,aIterator> bIterator;
typedef aIteratorBase<list<a>::const_iterator,bConstIterator> aConstIterator;
typedef bIteratorBase<list<b>::const_iterator,aConstIterator> bConstIterator;
***ここまで2***

でもこれだと(*1)の部分でbIteratorが未定義なので当然コンパイルできません。
最初の方法だと同じような記述がずらずらと続いて
見た目も美しくなく保守も大変なんですが、何か良いやり方はないでしょうか?


745 :デフォルトの名無しさん:02/05/30 00:51
>>744
ムリッ
定義が無限ループ入ってんじゃんかよ。
大人しくメンバーをポインタに汁!


746 :デフォルトの名無しさん:02/05/30 01:28
>>743
rdbuf()はbasic_iosからあるのでOKなのでは?


747 :デフォルトの名無しさん:02/05/30 02:11
>>774
typedef 使って
const有無は吸収したコード書くべし。


748 :739:02/05/30 05:16
できました!
rdbufでうまくいきましたです。サンクス!

749 :744:02/05/30 08:55
>>745
そうなんですけど、最初の方法ならば判読性を抜きにすれば
(5,6行目が相互依存ですが)実装自体可能なことは可能なんです。
メンバをポインタにするというのは・・・抜きの方向で。

>>747
あんまり慣れてなくてよく判らないんですが、
typedefを使ってconst有無を吸収するという場合の
何か取っ掛かりみたいなものはないでしょうか?


750 :デフォルトの名無しさん:02/05/30 10:29
>>749
HP版STLの実装を見よう。以上。

751 :デフォルトの名無しさん:02/05/30 10:35
>>744
そもそも 1 のほうもコンパイルできるとは思えんが。

752 :744:02/05/30 11:27
>>750
HP版というのはHewlett-Packardのことでしょうか。
探してみます。どうもありがとう。

>>751
とりあえずVC++(ver6,STLport)とg++(cygwin版2.95-3)では通ります。


753 :744:02/05/30 11:39
ぐはっ。HP版STLのLIST.Hを見てみました。
が、class list中でclass iteratorとclass const_iteratorを
それぞれについてベタで書いてありました・・・。
これだと1に書いた方法と似たり寄ったりになってしまって、
結局のところ解決にはならないです。

で以下のようにしてみたのですが今のところ問題ないようです。
>>744の2を少しいじりました)

template<typename T,typename U> class aIteratorBase; // predeclaration
template<typename T,typename U> class bIteratorBase; // predeclaration

template<typename T,typename U>
aIteratorBase : public itetaror_traits<T> { bIteratorBase<T,U> b; 〜; };
template<typename T,typename U>
bIteratorBase : public itetaror_traits<T> { aIteratorBase<T,U> a; 〜; };

typedef aIteratorBase<list<a>::iterator,list<b>::iterator> aIterator;
typedef bIteratorBase<list<a>::iterator,list<b>::iterator> bIterator;
typedef aIteratorBase<list<a>::const_iterator,list<b>::const_iterator> aConstIterator;
typedef bIteratorBase<list<a>::const_iterator,list<b>::const_iterator> bConstIterator;


754 :744:02/05/30 11:41
訂正(6行目)
誤:bIteratorBase : public itetaror_traits<T> { aIteratorBase<T,U> a; 〜; };
正:bIteratorBase : public itetaror_traits<U> { aIteratorBase<T,U> a; 〜; };

755 :デフォルトの名無しさん:02/05/30 12:07
>>753
テンプレートの引数は決まってるし、名前も決まってるんだから
そういう場合はやはり二つとも書かないと駄目。
typedefを使うのはコードの保守を楽にできるということが利点。
(typedefの定義を変えれば、共通してるところはこぴぺで済む)


756 :デフォルトの名無しさん:02/05/30 13:02
VC++ の std::string ってスレッドセーフじゃないですよね?
マルチスレッドアプリではどう回避すればいいのでしょう。
やっぱり STLport でしょうか。

757 :デフォルトの名無しさん:02/05/30 13:19
>>744
ホントにコンパイルは通ったの?マジで?
実際にインスタンスも生成できた?
クラスのサイズが無限大になるはずだが。


758 :744:02/05/30 13:47
>>757
ごめんなさい。>>744の1の5〜8行目の中身は
インスタンス(xIterator x;)ではなくて関数(xIterator func();)です。
# インスタンスだと通りませんが関数ならば通ります。

759 :757:02/05/30 13:53
>>744
ってか>>744の1でコンパイル通った事自体疑問なのだが。
今更だが改めて↓をコンパイルしてみたがもちろん通らん。
なんかコーディングミスで通ってない?

struct clsA;
struct clsB;
struct clsA{clsB b;};
struct clsB{clsA a;};

error:'b'が未定義のstruct 'clsB'で使用されています。


760 :757:02/05/30 13:55
リロード忘れてた。
>>759は無視して。
スンマソン。


761 :757:02/05/30 13:59
>>744
戻り値or引数で使うのであれば>>753-754
で文法的にも問題ないんじゃない。


762 :デフォルトの名無しさん:02/05/30 14:15
・・・と思ったが、戻り値or引数でもコンパイル通らねぇよ!
ヽ(`Д´)ノ ウワアァン!

struct clsA;
struct clsB;
struct clsA{clsB func(){return clsB();}};
struct clsB{clsA func(){return clsA();}};

error:認識できない型'clsB'が使われています。


763 :744:02/05/30 14:18
>>757
混乱させてしまって申し訳ないです。でも>>753でうまくいったかと思いきや

class X { 753の記述 };
XXX::aIterator a; // (*1)

のようにクラス内に入れると、VC++では(*1)のところで
aIteratorBase<〜>が未定義と言われてしまいコンパイルが通りません。
g++では通ります(゜ロ゜)。なんだか深みに陥りそうなので、
ひとまずは>>755が仰るようにベタで書いておいて、
簡潔に書く方法はfuture workにでもします。どうもでした。


764 :744:02/05/30 14:43
たびたびすみません。

>>762
>>744で端折り過ぎたんですが、実はこうなってました。
マジでごめんなさい。

template<typename T> struct clsA;
template<typename T> struct clsB;
template<typename T> struct clsA{clsB<T> func(){return clsB2();}};
template<typename T> struct clsB{clsA<T> func(){return clsA2();}};



clsA {
 clsA2 mSubstance;
 clsA(const clsA2& a) : mSubstance(a) {}
};

なんだか説明しながら自分でも整理できてきました。

765 :757:02/05/30 14:48
>>744
おぉ・・・gccでは通るのか。
漏れもパニくってしまったが、こういったモンは漏れも
たまに悩む時があるのでまた調べる気になったよ。
漏れも勉強になりました。


766 :盛り上がってるところすまんが:02/05/30 16:44
SGL版STLの実装を見よう。以上。

767 :デフォルトの名無しさん:02/05/30 23:54
Sing Like Talking がどうしたって?


768 :デフォルトの名無しさん:02/05/31 00:08
>>744
ああもう、どれにレスしていいかわからんが、とにかくだな、
・サイズの計算が必要なところに未定義のクラスを使うことはできない
・逆にいうと、サイズ計算が不要なら、名前の宣言だけで使うことはできる
つまり、
class A;
A foo(A a);
という宣言は OK (後で使わない限り) だが、
class a;
A foo() {
return A();
}
という定義は不可ってこと。よく考えろ。

769 :デフォルトの名無しさん:02/05/31 00:11
× class a;
○ class A;

770 :デフォルトの名無しさん:02/05/31 00:52
>>767
その単語はどこのお花畑から沸いて出ましたか。

771 :疲れた・・・原因分からなかったんだもん:02/05/31 12:07
VC++で、wchar_tをビルトイン型として扱う設定にしてあると、
STLPortの_Is_integer< wchar_t > がfalseを返してしまって、
basic_string< wchar_t >あたりが見事にこけますね・・・。

namespace std { template <> inline void _Construct< wchar_t >(wchar_t* __p) { *__p = 0;} }

をどっかに書いておいてやると大丈夫です。
外出だったら鬱だ・・・。


772 :鈴木宗男:02/06/04 16:37
マスコミの心無い誹謗中傷な記事に負けずに
今後も政治活動をがんばって行こうと思います。

ムネオAGE


773 :デフォルトの名無しさん:02/06/05 00:44
>>452
関数型言語の入門本でも読めば〜。
>>437もfunctional objectとか勉強しなおした方がいいかもね〜。

774 :デフォルトの名無しさん:02/06/05 01:01
773の4ヶ月に何があったのか……?

775 :デフォルトの名無しさん:02/06/05 01:07
>>452>>437はこの数ヶ月でスキルが神の域に達しているので、
>>773の出る幕は無い。余計なお世話でした〜。

776 :デフォルトの名無しさん:02/06/05 15:41
ってか>>773はそのレス書くのに
3ヵ月も調べてたんだ(w
( ´,_ゝ`)プッ


777 :デフォルトの名無しさん:02/06/05 18:21
ってか>>776はそのレス書くのに
半日以上かけたんだ(w
( ´,_ゝ`)プッ

778 :デフォルトの名無しさん:02/06/05 18:28
ってか>>777はそのレス書くのに
3時間近くもかけたんだ(w
( ´,_ゝ`)プッ


779 :デフォルトの名無しさん:02/06/05 18:33
>>778
じゃあ、俺は 5 分ということで終了 :-P

780 :デフォルトの名無しさん:02/06/07 01:53
age

781 :デフォルトの名無しさん:02/06/07 01:54
ってか>>780はたった3文字書くのに
丸一日以上かけたんだ(w
( ´,_ゝ`)プッ

782 :デフォルトの名無しさん:02/06/07 09:51
発言にもtemplateを使うスレはここですか?

783 :デフォルトの名無しさん:02/06/07 13:21
( ´,_ゝ`)プッ

784 :デフォルトの名無しさん:02/06/07 16:16
template<size_t N, char *T, char *U>
class pu
{
public:
  pu()
  {std::cout
   <<"ってか>>"<<N<<"はそのレス書くのに"<<std::endl
   <<T<<"も"<<U<<"たんだ(w"<<std::endl
   <<"( ´,_ゝ`)プッ"<<std::endl;}
  virtual ~pu(){}
};

…普通の関数の方がラクだった…。


785 :デフォルトの名無しさん:02/06/07 21:26
質問ですが、既存のコンテナクラスで
1.要素の追加が可能(削除はできなくてもよい)
2.要素のアドレスが変化しない(std::vectorは×)
3.ランダムアクセスが可能
のような性質を持ったものはないでしょうか?


786 :デフォルトの名無しさん:02/06/07 21:34
std::vector< T* >;
だめっすか?

787 :785:02/06/07 21:46
>>786
よさそうです・・・。
どうもありがとう。ちょっと考えてみます。


788 :デフォルトの名無しさん:02/06/07 21:54
>>785
std::vector<T> tbl(1000) ; // 多めに確保 resize禁止

っていうか、アドレスで参照しないようにしたほうが賢い。

789 :785:02/06/07 22:36
>>788
予想されるコンテナのサイズが1〜1000000と広いので、
多めに合わせて毎回1000000個確保するというのは気分的にちょっと・・・。
で、例えば1000個単位のブロックで要素を確保する
配列のラッパーみたいなものがあれば便利だなぁと思って質問しました。
# 作っても大した手間ではないんですが、あるものを利用したいなと。

790 :デフォルトの名無しさん:02/06/07 23:13
>>789
dequeは?

791 :デフォルトの名無しさん:02/06/07 23:13
map<int, T>

792 :785:02/06/08 00:08
いろいろどうもです。

>>790
std::dequeもstd::vectorと同じでコンテナサイズが大きくなると
リアロケーションが起きますよね?

>>791
まさに最初にやろうとしたのがmap<int,T>なんですが、
コンテナと要素の型を用途に応じてテンプレートで切り替えているので、
例えばlist,vector,set,mapでメンバ関数の整合性を取るのが結構大変になってます。
vectorやlistのようなインターフェース(->でメンバにアクセスできたり
ソートの基準が必要なかったり)で>>785に書いたことが出来ればいいなぁと・・・。
ちょっとソースの断片を貼っときます。

>>793



793 :785:02/06/08 00:09
template<typename X_CONTAINER, typename Y_CONTAINER>
class base {
 struct _vec_type{};
 struct _lst_type{};

 struct _x { std::list<_y*> ylist; typedef X_CONTAINER container_type; };
 struct _y { std::list<_x*> xlist; typedef Y_CONTAINER container_type; };

 // 要素x,yについて型とコンテナタイプを設定
 template<typename T, typename CONTAINER> struct _container_gen {};
 template<typename T> struct _container_gen<T,_vec_type> { typedef std::vector<T> type; };
 template<typename T> struct _container_gen<T,_lst_type> { typedef std::list<T> type; };
 typedef typename _container_gen<_x, X_CONTAINER>::type _xset;
 typedef typename _container_gen<_y, Y_CONTAINER>::type _yset;

 // 要素の集まり
 _xset xset;
 _yset yset;

 // n番目の要素を返す関数
 template<typename T>
 T element_forward__dispatch(T begin, int n, _vec_type) {
  return begin+n; // vector<>の場合はランダムアクセスで
 }
 template<typename T>
 T element_forward__dispatch(T begin, int n, _lst_type) {
  while (n) { ++begin; --n; } // list<>の場合はインクリメントで
  return begin;
 }
 template<typename T>
 T element_forward(T begin, int n) {
  typename T::container_type container;
  return element_forward__dispatch(begin,n,container);
 }
};

//使い方
base<_vec_type, _lst_type> a(100,100);
_x x = a.element_forward(xset,10); // 速い
_y y = a.element_forward(yset,10); // 遅い


794 :デフォルトの名無しさん:02/06/08 07:51
>>785
識別子を _ ではじめちゃだめじゃない?

795 :デフォルトの名無しさん:02/06/08 10:45
>>792
>std::dequeもstd::vectorと同じでコンテナサイズが大きくなると
>リアロケーションが起きますよね?
ほんとに起きる? とか聞いてみる。

796 :デフォルトの名無しさん:02/06/08 11:57
コンテナを切り替えるって…。
「そういう努力をしようとするな。それは努力の方向性が間違っている」
ってなことをEffectiveSTLに書いてあるんだが、それを知った上での狼藉か?

797 :デフォルトの名無しさん:02/06/08 12:42
>>795
起きる

798 :デフォルトの名無しさん:02/06/08 12:51
>>797
末尾(or 先頭)追加だけなら起きないんじゃないの?
http://www.dinkumware.com/htm_cpl/deque.html
>If an element is inserted at begin() or at end(), then all iterators become invalid,
>but no references that designate existing elements become invalid.
iteratorは無効になるけど、参照は無効にならない

799 :デフォルトの名無しさん:02/06/08 13:02
ではmapをラッピングしてvectorのように扱えるインターフェースを
提供してはどうか?
まずiteratorから改造が必要だが。
pairがからむあたりの汚さは確かに直交性を乱してると思う。

800 :デフォルトの名無しさん:02/06/08 13:07
VC7のHP版の実装を見る限りでは再割り当てが発生してるね。
ただしポインタの配列なので参照は変化しないと。

801 :デフォルトの名無しさん:02/06/08 13:14
>>800
VCについてるやつは、dinkumwareのものだよね。
dinkumware = P.J.Plauger
copyrightもHPとともに書かれてる(HP版を元にしている)。

単にHP版という言葉に反応しただけだが。

802 :デフォルトの名無しさん:02/06/08 13:57
>>789
>で、例えば1000個単位のブロックで要素を確保する
>配列のラッパーみたいなものがあれば便利だなぁと思って質問しました。
まんまdequeに見えるが…

803 :デフォルトの名無しさん:02/06/08 17:54
>>801
あっホントだ。
VC=HPという図式が以前からあったもんで、つい。

804 :785:02/06/08 18:03
>>795
std::dequeの実装を見た感じ、メモリの管理に関して
std::vectorとあんまり変わらないんですが・・・。

>>796
Effective STLは先週注文したところでまだ読んでません。
コンテナ切り替えは狼藉なんですか・・・。ん〜便利なんですけど。

>>797-798
実は2つのコンテナ(例えば>>793の_xsetと_yset)が相互のイテレータを
持つような構造になってまして、ここではiteratorが無効になることを
まさに避けたいのです。>>785の要望の「アドレスが変化しない」と書いたのは
正確には「イテレータが無効にならない」の誤りでした。すみません。

>>799
なんだか複雑になりそうで・・・。

>>802
リアロケーションさえ起きなければ・・・。
今考えてるのは一定サイズの配列■を
■-■-■-■-■-■-
のようなリスト構造にして、insert()やoperator++()を実装するものです。
欲しいものはとても単純なものなんです。


805 :デフォルトの名無しさん:02/06/08 23:17
参照の不変。
高速なランダムアクセス。
高速なサイズ拡張。
構造の単純さ。

もっとも近いところにあるのは単なるポインタの配列だ。
(もしくはスマートポインタの配列)
・・と逝ってみるテスト。

806 :デフォルトの名無しさん:02/06/08 23:17
>>804
> コンテナ切り替えは狼藉なんですか・・・。ん〜便利なんですけど。
便利? コンテナ固有のメソッドを呼んだ瞬間に 入れ替え不可能になるし、
固有のメソッドを呼ばないなら、そのコンテナを選択する意味はほとんどない
が……。

どうでも良いが、とりあえず規格書を読め。先頭に _ がある識別子を使っては
まずい理由やら、どのタイミングで iterator が invalid になるか明記してある。
あれこれ考えるのは、正しい情報を集めてからにしような。
(でないと効率悪いぞ)

807 :デフォルトの名無しさん:02/06/08 23:54
>>805
スマートポインタをコンテナに入れることはCOAP(Containers of auto_ptr)
と呼ばれ、禁止されている。boostのshared_ptrにすべきである。

808 :デフォルトの名無しさん:02/06/08 23:59
>>807
shared_ptrもスマートポインタですが

809 :デフォルトの名無しさん:02/06/09 00:08
>>808
スマソ。STLにスマートポインタを入れるなら、auto_ptrはダメで、shared_ptr
にしませう、という意味です。

810 :デフォルトの名無しさん:02/06/09 00:46
>>809
コピせずに常に参照を行うスタイルなら問題ない。

811 :デフォルトの名無しさん:02/06/09 01:13
>>810
アルゴリズムを適用した瞬間に、コンテナの中身がボロボロに壊れる(可能性が
ある)けどな。

812 :デフォルトの名無しさん:02/06/09 09:18
>>809
「STLに」→「STLコンテナに」

813 :デフォルトの名無しさん:02/06/09 22:37
>>810
規格ではコンテナにauto_ptrを入れられないようになっているはず。

814 :デフォルトの名無しさん:02/06/09 22:47
>>813
なってないよ

815 :デフォルトの名無しさん:02/06/09 23:50
>>813>>814
まあまあEffective STLのP39、第8項でもゆっくりと嫁。

816 :デフォルトの名無しさん:02/06/10 01:09
>>813
強制はしてない。ただし、そうなってるライブラリも増えてる。
(最近の STLport とか)

817 :デフォルトの名無しさん:02/06/10 01:29
多くのコンテナに入れる型は代入型の要件を満たしてなきゃいけないけど、auto_ptrは代入型ではないのでコンテナに入れてはいけないってことじゃないの?

818 :816:02/06/10 01:31
>>817
それは正しい。ただ、コンパイルエラーになるかどうかは実装依存ということで。

819 :デフォルトの名無しさん:02/06/12 15:26
try
{


820 :デフォルトの名無しさん:02/06/12 15:34
throw fatal_error();

821 :デフォルトの名無しさん:02/06/12 16:05
}
catch(kusores& res)
{
 thread<<">>"<<res<<"itteyoshi!"<<endl;
}


822 :デフォルトの名無しさん:02/06/12 16:22
signed char sc = 127;
sc++;        // (;´Д`)アァァ


823 :デフォルトの名無しさん:02/06/12 16:27
signed int money = INT_MAX;    //money → イパーイ(^∀^)
money++;               // (;´Д`)アァァ

824 :デフォルトの名無しさん:02/06/12 17:09
int *chubou=(int *)0;
*cubou=money;        // (;´Д`)アァァ


825 :デフォルトの名無しさん:02/06/12 21:12
>>819-824
STLを語れ

826 :w:02/06/13 10:49
std::vector<signed int> vi(1, INT_MAX);
vi[0]++;               // (;´Д`)アァァ


827 :デフォルトの名無しさん:02/06/13 11:49
VC++6でSTLport を入れたのですが、setの反復子が全部constで困ってます。
どうすればいいでしょう?

stl/_set.hで
typedef const_iterator iterator;
となっています。

const_castするしかない?

828 :デフォルトの名無しさん:02/06/13 12:20
>>827
setはソート済みコンテナ。
constはずすのは止めとけ。


829 :デフォルトの名無しさん:02/06/13 12:38
>>828
なんで? ソート順序に影響が「ない」ような変更を加える場合には const_cast
しても問題ないでしょう。

class Person
{
  int id; // こいつがソートキー
  string name;
};

これで name を(結婚に伴い)書き換える場合とかさ。

>>827
細かい考察は Effective STL の Item 22 が参考になるかと。

830 :デフォルトの名無しさん:02/06/13 12:51
>>829
そういう用途にはmapを使えよといいたい

831 :828:02/06/13 12:52
>>829
ソユコト

832 :デフォルトの名無しさん:02/06/13 22:36
>>829
http://www.dodgson.org/lab/hat/map_like_set.html
これを知った上で、mapにしろって言ってる?
もし知った上で言ってるんなら、その理由を教えて欲しいな。

833 :832:02/06/13 22:37
ごめん、レス番を間違えた。>>829じゃなくて、>>830に言いたかった。

834 :デフォルトの名無しさん:02/06/16 02:42
>>830ではないが、
なんかリンク先の話もあたりまえのことしか
書いてねーなぁ・・・もう少し意外なことが
あるかと期待してたんだが。

とりあえずリンク先の問題にしていることは、
「オブジェクト自身がキーを持っている場合…」
・冗長になる。
・重複する分領域を損する。

とりあえず解決策として、
・必ずしもクラスでまとめる必要がなければ
map。これでもキーと値はpairで一まとめで扱える。
・必ずクラスでまとめる必要があれば、
set。この場合、値を更新する場合はerase→insert。
ただしvalue_typeをコピーする必要があるため
コピーのオーバーヘッドがかかる。

コピーのオーバーヘッドもいやならconst_castで
いいんでないの?





漏れはしないけど。


835 :デフォルトの名無しさん:02/06/16 19:32
>>827
mutable を使うってのはどうよ。

836 :デフォルトの名無しさん:02/06/17 22:11
set の話は置いておいて

mutable って使ってますか

837 :デフォルトの名無しさん:02/06/17 22:24
>>836
あんまり使わないけど、使う。
使うときはほとんどキャッシュ用だね。
なんかの読み出しアクセサが重いときにキャッシュして高速化したりするときの
キャッシュ保持データに付ける。

838 :デフォルトの名無しさん:02/06/18 10:17
>837

キャッシュでも mutable にすると、思わぬバグの原因に
なったりしませんかね?

839 :デフォルトの名無しさん:02/06/18 16:20
>>838
慎重につかわないといけないのは確かだけど、
同じ目的ならconst_castよりは安全じゃないかな。

840 :デフォルトの名無しさん:02/06/20 18:07
std::vector<int*>みたいなのにソートアルゴリズムやもろもろのアルゴリズムを使うときに
std::less<int>とかがそのまま使えないけど みなさんはどうやってますか??
私はこんなの作ってしのいでますが・・・何かいい物がすでにあるのかな??
template<
class arg1,
class arg2,
class result,
class binary_function
>
class binary_ptr_ref_fun : public std::binary_function<arg1,arg2,result>
//ポインタを外して コンストラクタで渡した関数を実行してくれる関数オブジェクト
{
private:
binary_function func_;
public:
typedef arg1 first_argument_type; //bccのバグ? typedefしなおさないといけない(T_T)
typedef arg2 second_argument_type;
typedef result result_type;

binary_ptr_ref_fun(binary_function func) : func_(func){}
result_type operator()(first_argument_type val1,second_argument_type val2)
{
return (result_type)func_(*val1,*val2);
}
};

template<class arg,class binary_function>
binary_ptr_ref_fun<
arg,
arg,
binary_function::result_type,
binary_function
>
ptr_ref_fun2(binary_function func)
{
//binary_ptr_ref_funを作ってくれる関数
//スマートポインタなどにも使えるようコンテナに入ってる型は
//自分でtemplateパラメータを指定する
binary_ptr_ref_fun<
arg,
arg,
typename binary_function::result_type,
binary_function
> obj(func);
return obj;
}

こんな風に使ってます
std::vector<int*> v;
//vにいろいろ要素を追加
std::sort(v.begin(),v.end(),
ptr_ref_fun<int*>(std::less<int>()));

841 :デフォルトの名無しさん:02/06/20 18:09
ptr_ref_fun2<int*>(std::less<int>()));
最後の一行ミスってました(死

842 : ◆namco08. :02/06/20 23:06
>>840
汎用的すぎてかえって使いにくい気が。私は

struct DerefLess {
  template <typename T>
  bool operator()(const T& v1, const T& v2) const {
    return *v1 < *v2;
  }
};

// DerefLess() の typename 部分は、コンパイラが良きに計らう。
std::sort(v.begin(), v.end(), DerefLess());

ぐらいで妥協してます。ただ binary_function を継承していないから、not なんかと
組み合わせると問題アリですけどね。

843 :デフォルトの名無しさん:02/06/20 23:23
( ´D`)ふーん

844 :デフォルトの名無しさん:02/06/20 23:50
>>842
私も毎回そんなの書いてたので どうにか出来ないかと思い作ってみました
mem_funなどやnotやptr_funやbindなどと使えるけど確かにごちゃごちゃして
使いにくい部分もあります(死)

845 :デフォルトの名無しさん:02/06/21 01:59
>>840
こんなんどぅ?

template< typename T , typename P = T* >
struct asterisk : public std::unary_function< P , T& >
{
  T& operator () ( const P& p ) const { return *p; }
};
〜〜〜〜〜
std::sort( v.begin() , v.end()
    , boost::compose_f_gx_hy( std::less<int>()
                , asterisk<const int>()
                , asterisk<const int>() ) );


846 :デフォルトの名無しさん:02/06/21 03:05
>>845
いずれにせよ、

 テンプレートメンバ関数にすれば、functor の引数型はコンパイラにお任せ
 できるが、変換型関数オブジェクトにならない。

 テンプレートクラスにすれば、変換型関数オブジェクトになるが、functor の
 引数型は明示的に指定しなくてはならない。(スマートポインタの利用などを
 考えると、かなり面倒なことになりそう)

 compose 使えば汎用性は高くなるが、長くなって実際に指定するのが面倒。

ってことで、微妙に使いづらい気がする。スパッときれいに書けんものかね。

847 :デフォルトの名無しさん:02/06/21 03:15
boost::lambda って、かるーく見たところ、
  std::sort(v.begin(), v.end(), *_1 < *_2);
なんて書けそうなんだけど、ほんとかね?

848 :デフォルトの名無しさん:02/06/21 10:08
ご参考
boost::indirect_iterator


849 :デフォルトの名無しさん:02/06/22 03:15
おい、おまえら!!大変です。
日経ネットのザ・ランキング「日本サッカー史上初のW杯決勝トーナメント進出。功労者は誰?」でトルシエの通訳であるフローラン・ダバディ氏がサポーターの激しい反撃をくらって2位転落です。
今こそ2ちゃんの力を見せてください、おまいら!!
フローラン・ダバディをチェックして投票ボタンを押してくれ。
そしてコピペしる!!
http://rank.nikkei.co.jp/best10/rank.cfm


850 :デフォルトの名無しさん:02/06/22 03:35
Σ(゚д゚||)ガーン
俺ダバディ好きなんだよ。
投票しなくちゃ。

851 :850:02/06/22 03:38
つーか1位じゃん、意味無し。

1  フローラン・ダバディ 38830
2  サポーター 33838
3  フィリップ・トルシエ 4609
4  曽ケ端準 2682
5  中田英寿 2617
6  川口能活 1877
7  楢崎正剛 1541
8  稲本潤一 1335
9  宮本恒靖 1282
10  明神智和 1153
11  三都主アレサンドロ 1067
12  中田浩二 889
13  戸田和幸 657
14  柳沢敦 653
15  鈴木隆行 610
16  小野伸二 574
17  JAWOC 503
18  森島寛晃 409
19  秋田豊 320
20  市川大祐 271
21  松田直樹 269
22  中山雅史 225
23  服部年宏 207
24  福西崇史 206
25  小笠原満男 205
26  森岡隆三 204
27  西澤明訓 203


852 :デフォルトの名無しさん:02/06/22 03:41
つーか、何でトルシエよりダバディが上なんだ?

853 :デフォルトの名無しさん:02/06/22 04:02
>>851
あきらかにふざけているとしか思えない。
つーか、サポータが2位なのも自画自賛しているようでむかつく。

854 :デフォルトの名無しさん:02/06/22 11:18
>>853
同意
サポーターは別に何もしてないのに

855 :デフォルトの名無しさん:02/06/22 13:28
つーかネタなんでみんなマジレスすんなよ

856 :デフォルトの名無しさん:02/06/22 22:22
class hoge{
public:
 bool Show(std::ostream &os) = 0;
};
class hage{
public:
 bool Show(std::ostream &os){ os << "hageで悪いか!!\n"; return true; }
};
と言うクラスを
std::vector<hoge*> v;
v.push_back(new hage);
v.push_back(new hage);
v.push_back(new hage);

と言う風にして vの全ての要素に対してstd::coutを引数に渡してShowを呼び出したい。
そんな時にforを書くのはなんだか嫌なのでstd::for_eachでうまく済ませたい。
840のが使えるかと思いbindやらmem_fun_refなどを使ってやったがうまくいかない!
参照の参照になってエラーが出た。
みなやっぱりこういうのはforループまわしてやってるのかな??

857 :856:02/06/22 22:23
class hage -> class hage : public hoge{
間違えた スマソ

858 :デフォルトの名無しさん:02/06/22 23:12
>>856
Boost.org に行って mem_fn と ref をチェック。

859 :デフォルトの名無しさん:02/06/23 00:05
>>847
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/lambda/lambda.hpp>
using namespace std;
using namespace boost::lambda;
int main(int argc, char *argv[]) {
vector<int *> v;
v.push_back(new int(6));
v.push_back(new int(1));
v.push_back(new int(5));
sort(v.begin(), v.end(), *_2 < *_1);
for_each(v.begin(), v.end(), cout << *_1 << endl);
return 0;
}

860 :デフォルトの名無しさん:02/06/23 00:08
>>856
virtual忘れてるよ

#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
using namespace std;
using namespace boost::lambda;

class Base {public: virtual void hoge(ostream &os) = 0;};
class Derived : public Base
{public: virtual void hoge(ostream &os) {os << "hoge" << endl;}};

int main(int argc, char *argv[]) {
vector<Base *> v;
v.push_back(new Derived);
v.push_back(new Derived);
v.push_back(new Derived);
for_each(v.begin(), v.end(), bind(&Base::hoge, _1, var(cout)));
}

861 :デフォルトの名無しさん:02/06/23 00:39
#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>
using namespace std;

class Base {public:
virtual void hoge(ostream *os) = 0;};
class Derived : public Base {public:
virtual void hoge(ostream *os) {*os << "hoge" << endl;}};

int main(int argc, char *argv[]) {
vector<Base *> v;
v.push_back(new Derived);
v.push_back(new Derived);
v.push_back(new Derived);
for_each(v.begin(), v.end(), bind2nd(mem_fun(&Base::hoge), &cout));
}


862 :デフォルトの名無しさん:02/06/23 00:47
#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/bind.hpp>
using namespace std;

class Base {public:
virtual void hoge(ostream &os) = 0;};
class Derived : public Base {public:
virtual void hoge(ostream &os) {os << "hoge" << endl;}};

int main(int argc, char *argv[]) {
vector<Base *> v;
v.push_back(new Derived);
v.push_back(new Derived);
v.push_back(new Derived);
for_each(v.begin(), v.end(), boost::bind(&Base::hoge, _1, boost::ref(cout)));
}

863 :856:02/06/23 09:23
858-862
勉強不足でした
変に考えてた・・・mem_funが普通に使えるんだよね・・・鬱
bcc使ってるけどboost::lambda使った奴がコンパイル出来なかった
これがコンパイル出来るコンパイラってどんなのがある??


864 :デフォルトの名無しさん:02/06/23 12:35
俺だったらshared_ptrも使うな。

#include <vector>
#include <algorithm>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
using namespace std;
using namespace boost;

class Base {public: virtual void hoge(ostream& os) = 0;};
class Derived : public Base {public:
virtual void hoge(ostream& os) {os << "hoge" << endl;}};

int main(int argc, char *argv[]) {
vector<shared_ptr<Base> > v;
v.push_back(new Derived);
v.push_back(new Derived);
v.push_back(new Derived);
for_each(v.begin(), v.end(), bind(&Base::hoge, _1, boost::ref(cout)));
}

>>863
Windows上でlambdaが通るのはgccだけみたい。
http://www.boost.org/status/cs-win32.html
ここに各コンパイラの、機能対応表がある。

865 :863:02/06/23 16:06
>>864
丁寧にありがとうございました。


866 :デフォルトの名無しさん:02/06/25 10:59
std::vector<char> t(10);
strcpy( &t[0], "ABCD" );

ってコードを見かけたのだけど、これってヤバイよね。
vector<> って、確保された領域の連続性を保証しているのでしょうか?

867 :デフォルトの名無しさん:02/06/25 11:07
>>866
C言語の配列とメモリレイアウトの互換性があるので、大丈夫。
char t[10];
strcpy( &t[0], "ABCD" );
これと同等。

868 :デフォルトの名無しさん:02/06/25 11:48
>vector<> って、確保された領域の連続性を保証しているのでしょうか?
そのための vector です。

869 :デフォルトの名無しさん:02/06/25 14:28
>>868
たしか ANSI C++ の最初の規格書には記述が無くて、後から補遺に付け
加えられたんだっけ?

870 :デフォルトの名無しさん:02/06/25 18:19
>>869
ということは、領域の連続性の保証が規格として正式に決まったと理解してよい?

871 :デフォルトの名無しさん:02/06/25 19:29
いいよ。ただ注意なのは、>>866のコードで言う
strcpy( &t[0], "ABCD" );
はOKだけど、
strcpy(t.begin(), "ABCD" );
は実装依存になるからダメ。
iteratorはあくまでiterator。

872 :デフォルトの名無しさん:02/06/26 10:02
フッ
boostとSTLportは落とした。
問題内。

873 :デフォルトの名無しさん:02/06/26 10:07
いや、問題外

874 :デフォルトの名無しさん:02/06/26 14:41
いま要素の削除と追加を伴うコンテナにstd::vectorを使おうと思ってるのですが、
vector<T>かvector<T*>にするかで迷っています。
というのは要素の削除がvectorの途中[i]で発生したときに[i]と[end()-1]の要素を
スワップした後[end()-1]を削除することで対応しようと思っているのですが、
<T*>を使った場合、スワップはポインタの交換で済むのに対して
要素の追加はinsert(new T)としなければならず、
要素を一つ追加するたびにnewを呼ぶので遅くなりそうな気がします。
#insert(T)であればvectorのallocatorが適当な間隔でまとめて確保してくれる
#と思うのですが…。

何かオーソドックスな流儀とか方針というものがあれば教えてください。


875 :デフォルトの名無しさん:02/06/26 17:20
>>874
vector<T> なら new を呼ばないけど、T のコンストラクタ・コピーコンストラクタは
呼ばれるから、それほど軽い処理ではないよ。

もう少し要件を詰めた方が良いと思うな。何を重視してるの? もし

 コンテナ内の要素の順序は気にしない
 単に挿入・削除を早くしたい

だけなら list 使うのも手だし。

876 :874:02/06/26 17:41
>>875
ありがとう。

>コンテナ内の要素の順序は気にしない
>単に挿入・削除を早くしたい

この通りです。で削除には削除要素と最後尾要素のスワップが発生すると。
そしてvectorを使うのはランダムアクセスを速くしたいという理由からです。
vector<T>の要素追加がそれほど軽い処理ではない
(vector<T*>のinsert(new T)に比べて?)とのことですが、
たしかにいま両者を試してみたところ大きな違いはありませんでした。
となればvector<T*>の方が便利そうですね…。


877 :デフォルトの名無しさん:02/06/26 20:13
>>876
使ったこと無いくせにこういうのもなんだが、STLportを入れて
hash_mapを使うのが最適なんではなかろうか。

878 :デフォルトの名無しさん:02/06/26 20:17
insert(new T)
これは危険です。vectorが容量拡張時にメモリ確保に失敗したら T がメモリリークします。

より安全な書き方
T* t = new T;
try{
v.insert(t);
}catch(...){
delete t;
throw;
}

または
auto_ptr<T> t(new T);
v.insert(t.get());
t.release();

879 :874:02/06/26 23:59
>>878
親切にありがとうございます。
その方向で行くことにします。


880 :デフォルトの名無しさん:02/06/27 00:51
(゚ー^)b グッド

881 :デフォルトの名無しさん:02/06/27 01:37
856の言ってるような事(生のポインタじゃなくてスマートポインタ使って)
やる時にboostが駄目な状況だったらどうやってやる??

882 :デフォルトの名無しさん:02/06/27 02:44
>>881
boostが駄目な状況でコンテナにスマートポインタ入れたいなら、
自分でパチモン作るだろうねぇ。

883 :デフォルトの名無しさん:02/06/30 23:29
保守

884 :デフォルトの名無しさん:02/07/02 20:45
Every Little Thingがどうしたって!?


885 :デフォルトの名無しさん:02/07/03 06:55
>>844
当ててみな。

886 :デフォルトの名無しさん:02/07/03 22:45
最近c++ builderのMLで、
・vectorをコピーするときは、あらかじめresize等をしないとだめ
・コンテナのコンテナは(規格上)作れない
っていうこと書いている人がいるんだけど、本当?

http://dev.sfdata.ne.jp/cbuilder/htdocs/msg24962.html

STLPortの癖(バグ)ってことならまだ理解できるんだけど...。
MLに投稿すればいいってのは分かってるんだけど、
ヘタレなのでここで教えてください。

887 :デフォルトの名無しさん:02/07/03 23:10
>・vectorをコピーするときは、あらかじめresize等をしないとだめ
うそ。まさにコンテナ要件のところにそれ(コピー可能)がある。

>・コンテナのコンテナは(規格上)作れない
うそ。コンテナ要件はコンテナに格納するものの要件
(コピーコンストラクタと代入演算)を満たしている

はず


888 :デフォルトの名無しさん:02/07/03 23:11
>>887
どこのスレだったか探してる間に先越された・・

889 :デフォルトの名無しさん:02/07/04 01:07
>・コンテナのコンテナは(規格上)作れない

VC6 では確かにそのとおり
が、これはコンパイラのバグ

890 :デフォルトの名無しさん:02/07/04 01:32
>>889
とりあえず VC6 + STLport 4.5.3 だと vector<vector<int> > はコンパイル通った
けど。そういう話じゃなくて?

891 :デフォルトの名無しさん:02/07/04 01:54
なぬ?VCはコンテナのコンテナは作れないって?
それじゃ動的な二次元配列が作れないじゃないかよん。
あ、もちろんnewで、ってのは無しよ。

892 :デフォルトの名無しさん:02/07/04 02:52
VCのvector<vector<> >がヤヴァイなら世界中で大騒ぎになる罠。

893 :デフォルトの名無しさん:02/07/04 10:35
vector<vector<> > や vector<string > は連続したメモリに確保しようと
するから、ものすごく効率が悪いって話なのかな?


894 :デフォルトの名無しさん:02/07/04 11:03
>>893
えっ?

895 :デフォルトの名無しさん:02/07/04 11:16
>>893
あんた、たしかにだめぽ (w
vector<vector<T> > オブジェクトは、vector<T> オブジェクトを抱え込んでる
わけではないよ。さらに vector<T> オブジェクトは T オブジェクトを抱えこんでる
わけでもない。

896 :デフォルトの名無しさん:02/07/04 11:19
>>893
いろんな型 T で sizeof(vector<T>) してみれ。
>>895
その説明じゃわからんだろ。

897 :デフォルトの名無しさん:02/07/05 00:13
実は
vector<vector<T> >
ではなく
vector<vector<T>>
とかやってる罠?








と、言ってみる。てすっ


898 :名無しさん:02/07/09 00:42
mapのfor_eachでmapのsecondのメンバ関数を呼び出すことってできますでしょうか?

--------
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
#include <boost/bind.hpp>

class A
{
public:
int func(int i) { std::cout << "func:" << i << std::endl; return i; }
};

class B
{
public:
B(A& a)
{
m_bvec.push_back(a);
m_bmap.insert(std::make_pair(1, a));
}
void func(int i)
{
//std::for_each(m_bmap.begin(), m_bmap.end(), boost::bind(&A::func, _1.second, i));
std::for_each(m_bvec.begin(), m_bvec.end(), boost::bind(&A::func, _1, i));
}

std::map<int, A> m_bmap;
std::vector<A> m_bvec;
};

int main(char argc, char *argv[])
{
A a;
B b(a);
b.func(10);
return 0;
}
--------
こんなかんじなんですが、vectorだとちゃんとできるんですがmapだとどうもうまくいかなかったです。
for_eachを使わないとかパイプ用の関数を作ってやるとかでも対処できるんですが、
なんか素直じゃないようなかんじがするので。


899 :デフォルトの名無しさん:02/07/09 01:00
_1->second
というオチでは無く?

900 :898:02/07/09 01:41
>>899

それでもエラーがでてしまうんです。
エラーメッセージでは _1 の型情報を認識できていないっぽいんですが。


901 :デフォルトの名無しさん:02/07/09 11:04
select2ndってなかったっけ?

902 :898:02/07/09 21:41
>>901
select2nd でいけました。
ありがとうございました。


903 :デフォルトの名無しさん:02/07/10 03:54
下がりすぎ。たまには日の目を見ないと。
関係ないが、typeidっておもしろいな。

904 :デフォルトの名無しさん:02/07/10 14:42
ハァハァ汎用アルゴリズムたん(;´Д`)

905 :デフォルトの名無しさん:02/07/10 18:36
>>895
893じゃないけどちょっと質問。
std::vector<T>では『T型の値』が連続した空間に配置されてますよね?
# _M_insertはT*×N個ではなくT×N個でnewしてる(変な表現だけど…)。
たしかにstd::vectorは_M_start, _M_finish, _M_end_of_storageという
3つのポインタを持っているだけなのでsizeof(std::vector<T>)の返り値は
どんなTでも12になるけれど,それは実装形態の問題であって、
>>893の疑問を『抱え込んでるわけでもない』という理由で却下する意図が
よくわかりませんでした。いや…素朴な疑問なんですけど。


906 :デフォルトの名無しさん:02/07/10 18:57
いやそのまんま、vector<>は別に内包してる訳じゃないんだよ、で
いいんじゃない?
だから効率は関係ないよと。

907 :デフォルトの名無しさん:02/07/10 19:04
>>906
vector< vector< T > >って・・・まぁ T やサイズにもよるけど恐ろしく効率悪いと思われ
上位がリサイズで再割り当てされたら全ての T がコピーされるっしょ。

908 :デフォルトの名無しさん:02/07/10 19:19
>>907
>>893の言う効率に対してだよ。
でもまあvector<>のリサイズもvector<>ってそういうもんなんだから
しゃーないんちゃうん?



909 :デフォルトの名無しさん:02/07/10 20:33
g++でstd::mapのinsert時にout of memoryが出たんですが、
搭載メモリには十分な余裕があります。
mapの要素はノード単位で格納されると思うのですが、
メモリが足りているのにout of memoryが出るというのが解せません。
# 試しに同じコードをVC.NET(+STLPort)で走らせたのですが問題なく走りました。

g++とstd::mapという組み合わせに何かあるのでしょうか?


910 :デフォルトの名無しさん:02/07/10 22:29
>>909
まずは実行環境を書かないと。なんとなく UNIX 上で limit キツメに設定して
あるので、リソース制限に引っかかってるような気がするけど。

911 :909:02/07/10 22:52
>>910
どうもです。環境はWin2Kでcygwinを使ってます。g++のバージョンは2.95.3-5です。
メモリは1GB程度積んでますが、500MBくらいのところでout of memoryが出ます。
コマンドプロンプト上でtcshを使って、そこで走らせています。
# でも同じ環境からVC.NETでコンパイルした実行ファイルを走らせても問題ありません。

manでlimitとかdatasizeで検索したんですが
いまいちそれらしいオプションが見つけられずに悩んでいます。

912 :デフォルトの名無しさん:02/07/10 23:04
cygwinのせいじゃねーの?


913 :909:02/07/11 00:13
linuxのg++(2.96)だと問題なく走りました。
とりあえずcygwinのせいということにしておきます。


914 :デフォルトの名無しさん:02/07/11 02:10
>メモリは1GB程度積んでますが

どんなマシンなんだ・・・

915 :デフォルトの名無しさん:02/07/11 07:17
文字列のソートをするのに適したコンテナはなんですか?
"abc"
"Abc"
"Abcd"
などの文字列を登録可能で、且つ自動で辞書順にソートされている
コンテナはありますか?

916 :デフォルトの名無しさん:02/07/11 08:01
辞書順に比較する関数か関数オブジェクトが有ればどのコンテナでも可


917 :デフォルトの名無しさん:02/07/11 08:13
>>915
std::setかstd::multiset。場合によっては独自の比較関数。

918 :デフォルトの名無しさん:02/07/11 08:31
>916-917
ありがとうございます。


919 :デフォルトの名無しさん:02/07/11 12:57
>>914
今時、驚くほどでもないと思うけど。
DDR-SDRAMなら512MBが2枚で2万円程度。
ネタにマジレス スマソ。

920 :STL始めてさん:02/07/12 08:06
リストでinsertしたときに昇順で挿入されるにはどうすればいいのでしょうか?
それともinsert終了時にsort?
でもそれじゃ効率悪い罠

921 :920:02/07/12 08:21
んん?一回sortしてあったらそうでもないのかな???

922 :デフォルトの名無しさん:02/07/12 09:15
>>920>>921
insertion_sort()を自分で定義すればよい。

923 :920:02/07/12 09:33
継承して、ですか。
ちょっと使ってみるか程度に思っていたので、大変だなぁ。
テンプレとか、その他この他STL文法を理解していないのでとりあえずsortでいいや。
どうも!

924 :デフォルトの名無しさん:02/07/12 09:34
継承する必要なんか無いよ。
insertion_inserterを作ればいいんじゃないの?

925 :920:02/07/12 09:44
>>924
ぐは!
insertion_sortで検索したらいろいろ出てきました。
ぐるぐる回して比較して挿入するんですね。

#これくらい標準でついているかなぁと思ってました

926 :デフォルトの名無しさん:02/07/12 17:28
挿入ソートは、定数時間 O(N) で挿入できる。

927 :920:02/07/12 20:06
>>926
それは挿入ソートのほうがイイ ということでよろしいですか?

結局プログラムにsort自体が必要無いことに気づいて
重複無しpush_backを実装してなんとかなりました
デバッガでイテレータの中身がみれねえのが鬱

928 :920:02/07/12 20:11
自己レス
重複無しだったらsortしたほうがいいわな・・・ハァ

929 :デフォルトの名無しさん:02/07/12 21:02
>>927>>928
いえ、要素0個から挿入するなら、挿入時にソートすると速いのですよ。
そういうのを挿入ソートといいます。sort()を呼び出す必要がなくなります。

930 :デフォルトの名無しさん:02/07/12 21:30
要素数が多くなってくるとそうでもないよ。
単純なリストでは走査コストが、配列ではコピーコストがかさんでくる。

931 :デフォルトの名無しさん:02/07/12 21:41
>>930
そうだな。実際に時間を計ってみるとどうなるのかな。sort()はNlogN、挿入
ソートはNのオーダーだから、単純に考えると挿入ソートの方が速そうだ
が、係数がついてくるしな。

932 :920:02/07/12 22:02
>929-931
なるほど。深いですな
まぁ今僕が扱ってるデータ量だとミリ秒以下でそう
どうもです

933 :デフォルトの名無しさん:02/07/12 23:24
>>926
ソート済みのトコロに挿入するなら O(log n) だわな。ランダムアクセスイテレータ
使えれば、だけど。

n 個の要素を順に挿入していく場合、ソート済み配列を作るのに要する時間は
O(log n) で n 回挿入だからで結局 O(n log n)、挿入後にソートするのとオーダー
では変わらんよ。

934 :デフォルトの名無しさん:02/07/12 23:29
>>933
O(log n)のnは0〜nまで動くかと

935 :デフォルトの名無しさん:02/07/13 00:06
>>933
listコンテナだからランダムアクセスイテレータは使えんですよ。
そうなるとpush_back()してソートするのがオーダ的には一番速い
でよろしいか?

936 :デフォルトの名無しさん:02/07/13 12:27
>>934
それでも要素数 n に対して O(log n) と書く。O の定義がそうなってるから。

(一番重いところにかかってくるんだよな、O 表記って)

937 :デフォルトの名無しさん:02/07/13 14:19
あるstringのオブジェクトbufについて、'A'を検索し、"ABC"に置き換えたいのですが
以下に様にしてみました。まだコンパイルしていません。

std::string::size_type idx;
while((idx = buf.find('A')) != std::string::npos){
   if(idx == buf.begin() || *(idx - 1) != '\\'){//\はエスケープ
      buf.replace(idx, idx, "ABC");
      idx += strlen("ABC");
   }
   else
     ++idx;
}

ここで次の点がわかりません。
・replaceの引数はこれで大丈夫?
・'A'の前が'\\'であるのを確認するために*(idx-1)として良い?
・idxを進めるのにstrlen("ABC")で進めて良い?

どなたか教えてください


938 :デフォルトの名無しさん:02/07/13 14:26
>>936
n log n = log (n^n)
納k=1,n]log k = log (n!)
すなわちO(n log n)≠O(納k=1,n]log k)

939 :デフォルトの名無しさん:02/07/13 14:46
>>937
・ダメ
・ダメ
・いい

940 :デフォルトの名無しさん:02/07/13 17:22
>939
ありがとうございます

941 :939:02/07/13 17:49
>>940
それ以前に論外なところが多数あるので、よく考えろ

942 :デフォルトの名無しさん:02/07/13 20:11
setの内容をvectorに移そうとしています

std::set<string>::iterator idx;
for(idx = myset.begin(); idx != myset.end() ; ++idx){
myvect.insert(&(*idx));
}

ここでmyvectは
std::vector<string>です。

myvect.insert(&(*idx));
ってなんかへんじゃないスか?

setからvectorに内容をコピーするのにもっと優れた方法があるような気がしてます。
教えてください。お願いします


943 :デフォルトの名無しさん:02/07/13 20:21
myvect.insert(myvect.end(), myset.begin(), myset.end());

944 :デフォルトの名無しさん:02/07/13 20:23
copy()とinsert_iteratorを使ってはできませんか?

945 :デフォルトの名無しさん:02/07/13 20:24
>943
どうもありがとうございます。思い切り初心者なモンですみませんです。。

946 :デフォルトの名無しさん:02/07/13 20:25
>944
そんな方法もあるのですね?試してみます。
どうもです。

947 :デフォルトの名無しさん:02/07/13 20:28
>>944
copy(myvect.begin(), myvect.end(), inserter(myset, myset.end()); では?

948 :デフォルトの名無しさん:02/07/13 20:31
copy(myvect.begin(), myvect.end(), back_inserter(myset)); でもよいか。

949 :936:02/07/13 21:02
>>938
> 納k=1,n]log k = log (n!)
n! をスターリングの公式を使って近似してみ?

950 :デフォルトの名無しさん:02/07/13 21:27
>>948
逆だろ? myvect に入れたいって言ってる

>>942
vector<string>よりlist<string>のほうが効率がいいのとちゃうか?

951 :デフォルトの名無しさん:02/07/13 22:03
>>949
スターリングの公式:n!〜√(2πn)n^n/e^n
つまりn log nより納k=1,n]log kの方が断然オーダーが小さい


952 :デフォルトの名無しさん:02/07/13 22:16
もちろんO(log n!)⇒O(n log n)なんだけども
どちらかというとo(n log n)だというだけ

953 :デフォルトの名無しさん:02/07/13 22:18
>>951
log( n! )
〜 log( √(2πn)n^n/e^n )
〜 log( √2πn ) + log( n^n ) - log( e^n )
〜 log n + n log n - n
O( n log n ) > O(log n) && O( n log n ) > O( n) より
O( log(n!) ) == O( n log n ) ■

954 :951:02/07/13 22:44
>>953
君が正しい

955 :デフォルトの名無しさん:02/07/15 08:21
>>948
943 の方が正解(VC6のSTLを除く)

956 :デフォルトの名無しさん:02/07/15 13:45
>>960
次スレよろ

957 :デフォルトの名無しさん:02/07/16 00:37
mem_fun_ref を使うとインライン展開されないので困った
という場合、自分でループをまわしたらいいんでしょうか?

958 :デフォルトの名無しさん:02/07/16 08:49
必要そうなリンク
STLPort
http://www.stlport.org/
VC++のSTLバグ
http://www.dinkumware.com/vc_fixes.html
ISO/IEC 14882
Programming languages -- C++
http://webstore.ansi.org/ansidocstore/product.asp?sku=ISO%2FIEC+14882%2D1998
http://www.kuzbass.ru/docs/isocpp/

あと適当なサイト(いらんか?)
http://www-scc.tokyo.jst.go.jp/riyou/users/users_guide/ucoma/FJcompiler/C++/stdlib/stdug/general/
http://www.wakhok.ac.jp/~sumi/stl/

959 :デフォルトの名無しさん:02/07/16 13:05
どちらかと言うと、
myvect.reserve(myset.size());
copy(myset.begin(), myset.end(), back_inserter(myvect));
の方がよろしいかと。


960 :デフォルトの名無しさん:02/07/16 13:25
次すれそろそろ?

961 :デフォルトの名無しさん:02/07/16 13:47
>>960
960の方です。
次ぎスレよろ。


962 :デフォルトの名無しさん:02/07/16 13:53
part2
http://pc.2ch.net/test/read.cgi/tech/1026793823/

261 KB
■ このスレッドは過去ログ倉庫に格納されています

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.02 2018/11/22 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)