文字列をコンテナに格納するには?

解決


TnR  2008-05-05 23:27:28  No: 68243  IP: 192.*.*.*

std::map を使って、int と 文字列をペアにして保持したいのですが
格納か取得が出来ていないようで、困っています。宜しければご教示お願いします。
VC6で、MFCは使っていません。

#include <map>
typedef std::map<int, LPCTSTR> StrMap;

StrMap menuMap;

として使っています。入力をするときは、

void クラス名::Insert(int id, LPCTSTR filePath) {
  menuMap.insert(std::pair<int, LPCTSTR>(id, filePath));
}

です。出力するときは、

void クラス名::Get(int id) {
  if (menuMap.count(id)) {
    StrMap::iterator itr = menuMap.find(id);
    if (itr != menuMap.end()) {
      MessageBox(NULL, itr->second, "", MB_OK);
    }
  }
}

のようにしています。
取得時に itr->second の値が "フフフフフ" のようになっていることを
確認しました。

どうすれば文字列を格納出来るのでしょうか?

STLはあまり使ったことないのですが、勉強したく、このようにしました。
それと、文字列には TCHAR を使っています。
よろしくお願いします。

編集 削除
επιστημη  URL  2008-05-05 23:59:05  No: 68244  IP: 192.*.*.*

おそらくinsert時のミスでしょう。

std::pair<int, LPCTSTR> の second は"ただのポインタ" であることを忘れずに。

わかんないなら
map<int,std::string> あるいは map<int,std::wstring> 使うが無難です。

編集 削除
TnR  2008-05-06 00:22:14  No: 68245  IP: 192.*.*.*

επιστημηさん、ありがとうございます。

> std::pair<int, LPCTSTR> の second は"ただのポインタ" であることを忘れずに。

なるほど、ポインタの寿命が切れているということでしょうか。

なんとか
std::pair<int, TCHAR[_MAX_PATH]> のようなことが出来ませんでしょうか?

使うと、
cannot specify explicit initializer for arrays
see declaration of 'second
と表示されてしまいます。
恐らく、"配列は使えません"のような意味だと思います。

プログラムは結構大きく、Insertメソッドを呼ぶ側は
TCHAR filePath[_MAX_PATH] を渡しています。


> map<int,std::string> あるいは map<int,std::wstring> 使うが無難です。

#include   <string>
#include      <map>
typedef std::string String;
typedef std::map<int, String> StrMap;

として、Insert を
void cHSP::InsertEZMenu(int id, LPCTSTR filePath) {
  String str(filePath);
  menuMap.insert(std::pair<int, String>(id, str));
}

とすると、見事取得も成功しました!
調べながらで、変なコードかも知れません(すみません)。


しかし、なぜ std::string だと大丈夫なのでしょうか?
Insert関数のスコープを抜けた時に、stringのデストラクタが
動くような気がするのですが・・・

それとも最初からスコープの問題ではないのでしょうか?
宜しくお願いします。

編集 削除
επιστημη  URL  2008-05-06 00:34:21  No: 68246  IP: 192.*.*.*

> しかし、なぜ std::string だと大丈夫なのでしょうか?
> Insert関数のスコープを抜けた時に、stringのデストラクタが
> 動くような気がするのですが・・・

map内にはinsertの引数で渡したstringの"コピー"が格納されるので
デストラクトされても無問題なのね。

編集 削除
επιστημη  URL  2008-05-06 00:42:27  No: 68247  IP: 192.*.*.*

おぼえがき。

> typedef std::string String;

typedef std::basic_string<TCHAR> String;
とするが吉でしょう。

> void cHSP::InsertEZMenu(int id, LPCTSTR filePath) {
>   String str(filePath);
>  menuMap.insert(std::pair<int, String>(id, str));
>}

void cHSP::InsertEZMenu(int id, LPCTSTR filePath) {
  menuMap.insert(std::pair<int, String>(id, filePath));
}
で十分。LPCTSTRから暗黙のコンストラクトが行われます。

編集 削除
TnR  2008-05-06 00:45:12  No: 68248  IP: 192.*.*.*

επιστημηさん、
どうもありがとうございます!

> map内にはinsertの引数で渡したstringの"コピー"が格納されるので
デストラクトされても無問題なのね。

すごく納得できました。
ポインタの時も、ポインタ自体の値がコピーされていたのですね。
(・・・これは当たり前ですね)

つまり、文字列を保持できるクラス(構造体でも)を用意すればOKで、
既に用意されてるstd::stringが使えます、ということでしょうか。

本当にありがとうございました!

編集 削除
TnR  2008-05-06 00:51:03  No: 68249  IP: 192.*.*.*

επιστημηさん、
おぼえがき、とても参考になります。

今までずっとTCHARや独自文字列用クラスを使っていたのですが、
こんなに std::string が手軽だと分かりましたので、
これからどんどん使っていこうと思います。

STLってスゴイですね。
どうもありがとうございます。

編集 削除