map::find()の戻り値が変数に入ってくれません。

このQ&Aのポイント
  • map::find()の戻り値が変数に入ってくれません。
  • std::map<ユーザー型,ユーザー型>::iteratorを定義しないといけないのでしょうか?
  • どなたかお知恵をお貸しください。
回答を見る
  • ベストアンサー

map::find()の戻り値が変数に入ってくれません。

こんにちは、boundaryといいます。 ユーザー型のキーとユーザー型の値をmapに挿入したのです が、map::find()の戻り値が変数に入ってくれません。 operator=を定義しないといけないのかなと思いやってみた のですがうまくいきません。 std::map<ユーザー型,ユーザー型>::iteratorを定義しない といけないのでしょうか? どなたかお知恵をお貸しください。 よろしくおねがいします。 windows2000 vc6.0sp5 ps.ソースコードを載せようとしたのですが、質問文字数が 最長文字数を超えるようで質問する事ができません。 ですのでかなり端折っています。(スミマセン) /* mapのキーです。 */ typedef struct _StateAndReturn { int State; int Return; } StateAndReturn; /* mapの値です。 */ struct NextStateAndFunc { NextStateAndFunc& operator=(const NextStateAndFunc& X){ NextState = X.NextState; MemFuncPointer = X.MemFuncPointer; } typedef int (Funcs::*pFunc)(); int NextState; pFunc MemFuncPointer; }; class CEventMap { private: typedef int (Funcs::*pFunc)(); typedef map<StateAndReturn, NextStateAndFunc, my_less> _EventFuncMap; _EventFuncMap EventFuncMap; public: void Set(int StateNow, int ServerReturnCode, int StateNext, pFunc pF) { /*登録します。*/ } const NextStateAndFunc Answer(int StateNow, int ServerReturnCode) { StateAndReturn tempStateAndReturn; tempStateAndReturn.State = StateNow; tempStateAndReturn.Return = ServerReturnCode; map<StateAndReturn, NextStateAndFunc>::const_iterator ite; ite = EventFuncMap.find(tempStateAndReturn); /* ←ここでエラーになります。 */ return ite->second; } };

noname#4877
noname#4877

質問者が選んだベストアンサー

  • ベストアンサー
  • Fooky
  • ベストアンサー率71% (59/82)
回答No.2

うちの環境(コンパイラ:gcc,OS:Linux)でStateAndReturn,NextStateAndFunc,my_less,_EventFuncMapを下記の通りに,Funcsを適当に定義してから問題の行を書いたんですが,コンパイラエラーは出ませんでした.やはりVCのmap::iteratorの実装方法に依存した問題のようで,私の方ではお手上げです. 多分,試されてると思いますが,代入方法などをいろいろ変えて回避するしかないように思います. 1.コピーコンストラクタ: ...>::const_iterator ite(EventFuncMap.find(...)); 2.反復子にコピーしない: return EventFuncMap.find(...)->second; 3.iteをconst_iteratorではなくiteratorにしてみる(エラーメッセージからはfindの出力はconst_iterator&ではなくiterator&になっているようなので) 他にも回避策はあるかもしれませんが,思いついたのはこれくらいです.

その他の回答 (1)

  • Fooky
  • ベストアンサー率71% (59/82)
回答No.1

どういうエラーになるんですか?ぱっと見たところ,反復子との型の不一致ということは無いんですか? map<StateAndReturn, NextStateAndFunc, my_less> EventFuncMap; なのに, map<StateAndReturn, NextStateAndFunc>::const_iterator ite; で ite = EventFuncMap.find(...); という風に受けているのが問題なのかなと. map<StateAndReturn, NextStateAndFunc, my_less>::const_iterator ite; で受けてもだめなんでしょうか.

noname#4877
質問者

お礼

こんにちは、boundaryです。 とりあえず解決しました。 とあるホームページのとある方より正しいコードを頂戴しました。 (その際、クロスポストのお叱りを受けました。失礼しました。) またまた最大投稿文字数の関係で全てを記述できないので、 要点にまとめて書きます。 struct StateAndReturn { int State; int Return; StateAndReturn(int s =0, int r =0) : State(s), Return(r) {} }; template<typename F> struct NextStateAndFunc { typedef int (F::*func_type)(); int NextState; func_type MemFuncPointer; NextStateAndFunc(int s =0, func_type f =0) : NextState(s), MemFuncPointer(f) {} }; とし、 typedef typename NextStateAndFunc<F>::func_type func_type; typedef std::map<StateAndReturn, NextStateAndFunc<F>, my_less> map_type; template<typename F> const NextStateAndFunc<F> CEventManager<F>::Answer(int StateNow, int ServerReturnCode) { typename map_type::const_iterator ite = EventFuncMap.find(StateAndReturn(StateNow,ServerReturnCode)); return ite->second; } との事です。 僕のとの違いを今考えているのですが正直言ってよくわかりません。(^◇^) 違いはメンバ関数スコープ内にローカルオブジェクトを作ってmap::find()のと メンバ関数の引数としての一時オブジェクトをmap::find()に渡してるだけだと 思うのですが、(-.-;)y-~~~ 何分初心者ですので(テンポラリなセリフ・・・)しばしゆっくり考えてみたいと思います。 ありがとうございました。q( ̄ω ̄)p

noname#4877
質問者

補足

こんにちは、Fookyさん。 お返事ありがとうございます。 >反復子との型の不一致ということは無いんですか? すみません。貼り付け間違いました。 map<StateAndReturn, NextStateAndFunc>::const_iterator ite; ← × map<StateAndReturn, NextStateAndFunc, my_less>::const_iterator ite; ← ○ my_lessは、 struct my_less : binary_function<_StateAndReturn, _StateAndReturn, bool>{ bool operator()(const _StateAndReturn& x, const _StateAndReturn& y){ return x.State < y.State; } }; としてます。  エラーの内容ですが、 error C2679: 二項演算子 '=' : 型 'class std::_Tree<struct _StateAndReturn,struct std::pair<struct _StateAndReturn const ,struct NextStateAndFunc>,struct std::map<struct _StateAndReturn,struct NextStateAndFunc,struct my_less,class std::allocator<struct NextStateAndFunc> >::_Kfn,struct my_less,class std::allocator<struct NextStateAndFunc> >::iterator' の右オペランドを扱う演算子は定義されていません。(または変換できません)(新しい動作; ヘルプを参照) となっています。

関連するQ&A

  • 新たに定義したクラスでmapを作成する場合

    STLのmapを使っているのですが、自分で定義したクラス(便宜上Keyと書きます)をキーにすると想定した動作になりません。 insert、iteratorによる参照はできるのですが、findがうまくいっていないようです。 値を見ると探しているキーと同じものが入っているのですが、2つのKeyのインスタンスが同一であるということが認識されていないのかfindの結果は(mapの名前).end()になってしまいます。 Keyのオペレータとして'<'は定義しましたが、「同一である」ことを示すために別のオペレータを定義する必要があるのでしょうか? あてずっぽうで'=='を定義してみましたがうまくいきません。 お知恵を拝借できればと思います。よろしくお願いします。

  • C++ の map についてです

    C++の初心者です。よろしくお願いします。 DirectXを使っていて簡単なゲームを作っていまして、 mapを使っていると、このようなエラーが出てしまいどうしても理由わかりませんでした。 class D2DMap : public GameTexture{ protected: GameTexture** CopyTexture; int MaxMass; int WidthMass; int HeightMass; int WidthMassPixel; int HeightMassPixel; int MassInfo[30][30]; public: D2DMap(); virtual ~D2DMap(); HRESULT LoadMapTexture(int widthmass, int widthmasspixel,int heightmass, int heightmasspixel, const char* FileName, D3DCOLOR color); HRESULT LoadTextMass(const char* FileName); int GetWidthMassPixel(){ return WidthMassPixel;} int GetWidthMassNum(){ return WidthMass;} int GetHeightMassPixel(){ return HeightMassPixel;} int GetHeightMassNum(){ return HeightMass;} int GetMassInfo(int x, int y){ return MassInfo[y][x];} void DrawMap(D3DCOLOR color); void DrawCopyMap(D3DCOLOR color); void SetCopyTex(GameTexture* copy){ CopyTexture= &copy;} void Delete(){} }; map<string , D2DMap*> MapBox; と定義して string Name="--------"; D2DMap map; MapBox.insert( map<string, D2DMap*>::value_type(Name, &map)); としたとこと error C2275: 'std::string' : この型は演算子として使用できません 'std::string' の宣言を確認してください。 error C2059: 構文エラー : '>' error C2039: 'value_type' : '`global namespace'' のメンバではありません というエラーが出てきました。 mapのfind や iterator は可能なのですがinsertの場合エラー となり、理由が全く分かりません。詳しい方アドバイスをお願いしたい のですが、よろしくお願いします。 VC++2008 を使っています。

  • ファイル名リストの置換処理

    以前、ファイルリストの取得について教えて頂きました。ありがとうございます。 取得したリストを文字列で入れ替えるにはどうすればよいでしょうか 例えば取得したリストの最初の位置の文字列dml[0]をEcoDataFileNameと置き換えたいです。 #include <Windows.h> #include <map> #include <vector> #include <string> #include <iostream> #include "time.h" using namespace std; bool operator<(const FILETIME& x, const FILETIME& y) { if ( x.dwHighDateTime < y.dwHighDateTime ) return true; if ( y.dwHighDateTime < x.dwHighDateTime ) return false; return x.dwLowDateTime < y.dwLowDateTime; } class DML_Backup { vector<string> files_; public: void search(const char* spec) { typedef multimap<FILETIME,string> map_type; map_type files; WIN32_FIND_DATAA find_data; HANDLE handle = FindFirstFileA(spec, &find_data); if ( handle != INVALID_HANDLE_VALUE) { do {   files.insert(map_type::value_type(find_data.ftLastWriteTime, find_data.cFileName)); } while ( FindNextFileA( handle, &find_data) ); FindClose(handle); } files_.clear(); for ( map_type::iterator iter = files.begin(); iter != files.end(); ++iter ) { files_.push_back(iter->second); } } string operator[](int inx) const { return files_.at(inx).c_str(); } int size() const { return files_.size(); } }; int main() { DML_Backup dml; char EcoDataFileName="MonJun131956122011.ecd"; dml.search("*.ecd"); }

  • DXライブラリでマップが作れません・・・。

    今DXライブラリとVisualC++2008を使ってゲーム(アクション)を作っているのですがマップが作れません・・・、構造体?をつかってマップの描写は成功したのですが、0のところに判定を持たせることができません・・・。どのようにすればいいのでしょうか?色々試してみてもできず困っています。 ソースの一部 #include"DxLib.h" #define MAP_SIZE 64 // マップチップ一つのドットサイズ #define MAP_WIDTH 10 // マップの幅 #define MAP_HEIGHT 8 // マップの縦長さ int MapData[ MAP_HEIGHT ][ MAP_WIDTH ] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 } , { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } , } ; void HYOUZI(void); void SYOKIKA(void); struct dousa{ int power; int flag; }; struct dousa jump; struct zahyou { int x,y; int img; int flag; int muki_y; int muki_x; int x1; int x2; int x3; int x4; int y1; int y2; int y3; int y4; }; struct zahyou haikei; struct charcter { int x,y; int img; int flag; }; struct charcter ziki; struct map; //初期化 void SYOKIKA(void){ jump.flag=0; ziki.x=100; ziki.y=100; ziki.img=LoadGraph("red_player.bmp"); } //背景 void HYOUZI(void){ int i,j; for( i = 0 ; i < MAP_HEIGHT ; i ++ ) { for( j = 0 ; j < MAP_WIDTH ; j ++ ) { if( MapData[ i ][ j ] == 0 ) { DrawBox( j * MAP_SIZE , i * MAP_SIZE , j * MAP_SIZE + MAP_SIZE , i * MAP_SIZE + MAP_SIZE , GetColor( 255 , 0 , 0 ) , TRUE ) ; } } } DrawGraph(ziki.x,ziki.y,ziki.img,TRUE); ScreenFlip(); } //動き void ugoki(void){ int OldX , OldY ; OldX = ziki.x ; OldY = ziki.y ; if (CheckHitKey(KEY_INPUT_RIGHT) == 1){ ziki.x=ziki.x+4; } if (CheckHitKey(KEY_INPUT_RIGHT) == 1) if (CheckHitKey(KEY_INPUT_Z) == 1) { ziki.x=ziki.x+8; } if (CheckHitKey(KEY_INPUT_LEFT) == 1){ ziki.x=ziki.x-4; } if (CheckHitKey(KEY_INPUT_LEFT) == 1) if (CheckHitKey(KEY_INPUT_Z) == 1) { ziki.x=ziki.x-8; } if(ziki.x>640){ ziki.x=-10; } if(ziki.x<-10){ ziki.x=640; } //ジャンプ jump.power-=1; ziki.y -=jump.power; if(ziki.y>400){ jump.power=0; ziki.y=400; jump.flag=0; } if (CheckHitKey(KEY_INPUT_DOWN) == 1 && jump.flag == 0){ jump.power=30; jump.flag=1; } if (CheckHitKey(KEY_INPUT_UP) == 1 && jump.flag == 0){ jump.power=20; jump.flag=1; } if( MapData[ ziki.x ][ ziki.y ] == 0 ) { ziki.x = OldX ; ziki.y = OldY ; } } int WINAPI WinMain ( HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { ChangeWindowMode(TRUE); if(DxLib_Init()==-1) { return -1; } SYOKIKA(); SetDrawScreen(DX_SCREEN_BACK); while(ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0){ HYOUZI(); ugoki(); ClearDrawScreen(); } DxLib_End(); return(0); } 分かる人がいたらぜひ教えてください(o_ _)o

  • STL MAPのキー

    3種類のキーを持ったデータの検索をしたいのですが、 mapで実現する場合、どんな方法があるのでしょうか キー int A、キー int B、キー string C、VOL=クラスX 検索はA,B,Cでそれぞれ行うとした場合、以下のようなmapのtypedefを3種類設定することになるのでしょうか? map<int, クラスX> aa; map<int, クラスX> bb; map<string, クラスX> cc; これですと削除がする場合には3箇所mapを修正するひつようがありますので1箇所で処理でしないのでしょうか?

  • 新しい順のリスト取得

    この件につきましては、特定の回答者の方のおかげで収束につながりました。あとひとつだけお力をください。ファイルの古い順にリストを作成してもらいましたが、これに新しい順にソートする機能を追加したいです。これで仕様としては終わりです。どうかよろしくお願いいたします bool operator<(const FILETIME& x, const FILETIME& y) { if ( x.dwHighDateTime < y.dwHighDateTime ) return true; if ( y.dwHighDateTime < x.dwHighDateTime ) return false; return x.dwLowDateTime < y.dwLowDateTime; } class DML_Backup { public: vector<string> files_; void search(const char* spec) { typedef multimap<FILETIME,string> map_type; map_type files; WIN32_FIND_DATAA find_data; HANDLE handle = FindFirstFileA(spec, &find_data); if ( handle != INVALID_HANDLE_VALUE) { do { files.insert(map_type::value_type(find_data.ftLastWriteTime, find_data.cFileName)); } while ( FindNextFileA( handle, &find_data) ); FindClose(handle); } files_.clear(); for ( map_type::iterator iter = files.begin(); iter != files.end(); ++iter ) { files_.push_back(iter->second);         } }

  • 仮想基底クラスをもつクラスの代入演算

    仮想基底クラスをもつクラスの代入演算で、仮想基底クラスの代入が各々のサブオブジェクトにつきただ一回なされるようにしたい場合に、みなさん、どのように設計されていますか? 何か、手軽なテクニックがあれば、ご教示ください。 ===(コンストラクタなどは略、アクセス制御も略) たとえば、 struct X { int x; }; struct A : virtual X { int a; }; struct B : virtual X { int b; }; struct C : A, B { int c; }; int main() { C c1, c2; c1 = c2; } として、デフォルト代入に頼ると、c1.x への c2.x の代入を複数回行うコンパイラが多いですよね(というか、きっちり1回のみ行うようにしているコンパイラに出会ったことがない)。C++標準でも、初期化はただ一度とコンパイラが保証するようになっていますが、代入は何度代入してもいいようになっていたと思います。 以下のように、各クラスで、直接の非仮想基底クラスと自身のデータメンバにのみ代入するメンバ関数を定義して、最派生クラスでのみ、仮想基底クラスの代入を行うのが、普通のやり方なんでしょうか。 これでもいいのですが、後に、ある基底クラスに仮想クラスが付け加わったりすると、その基底クラスから派生しているクラスの代入演算の定義をすべていじらないといけなくなるので、もっといいテクニックがあるのなら、と思いまして質問したしだいです。 struct X { int x; X &nvAssign(const X &z) { x = z.x; return *this; } X &operator=(const X &z) { nvAssign(z); } }; struct A : virtual X { int a; A &nvAssign(const A &z) { a = z.a; return *this; } A &operator=(const A &z) { X::nvAssign(z); return nvAssign(z); } }; struct B : virtual X { int b; B &nvAssign(const B &z) { b = z.b; return *this; } B &operator=(const B &z) { X::nvAssign(z); return nvAssign(z); } }; struct C : A, B { int c; C &nvAssign(const C &z) { A::nvAssign(z); B::nvAssign(z); c = z.c; return *this; } C &operator=(const C &z) { X::nvAssign(z); return nvAssign(z); } }; === 1. 仮想基底クラスは何度代入されてもいいようにするもんだ。 2. 仮想基底クラスにデータメンバを持たせるのは間違いだ。 3. 遅くなるから、そもそも仮想基底クラスなど使わない。 という回答は無しでお願いいたします。たぶん、1 か 2 が正解なんでしょうけど^^

  • 【C言語】戻り値が構造体の関数

    こんにちは。 授業でC原語を習っており、その課題で詰まった所についての質問です。 ※以下の関数については可能な限り簡略化しています。 typedef struct {   char name[10];   int height; } Person; Person *bin_search( const Person *key) {   return (&key); } 以上のような構造体と関数があった場合、bin_searchでkeyを返したいのですが、 return (&key); では、コンパイルするとその行について return from incompatible pointer type warning: function returns address of local variable とエラーが出てしまいます。 return (key); return (*key); などとりあえず試してはみたのですがどれも上手くいきません。 そもそも関数名の前に*(間接演算子?)があること自体がよくわかっていないです…… なので、返り値をどうすれば正しく機能してくれるのか教えていただけるとありがたいです。 ※課題で指定されているので、関数頭部については変更しないとします。

  • 24ビットの変数

    はじめまして。 WinXP pro(SP2) VC6.0(SP6) MFC使用です。 とある理由から24bit(3byte)の整数型変数の型を 作っています(仮にINT24とします)。 その変数が満たさなければならない条件として (1)サイズが3バイトである(sizeof(INT24) == 3) (2)INT24 nInt24 = nValue(int型の変数)という形で使える (3)int nValue = nInt24(INT24型の変数)という形で使える というのがあります。 それで、構造体を使用して下のように 定義をしました。 typedef struct tagInt24 {   BYTE byData[3];   void operator = (int nValue)   {     byData[0] = (nValue & 0x0000FF);     byData[1] = ((nValue & 0x00FF00) >> 8);     byData[2] = ((nValue & 0xFF0000) >> 16);   }; }INT24, *LPINT24; これで(1)と(2)は満たせるのですが (3)をどうやって実現するのか悩んでおります。 どなたか知恵をお貸しいただけないでしょうか。

  • MAPコンテナの宣言部分の表記に関して質問です

    C++でSTLのMAPを勉強しだしたのですが、 よく分からない部分を見つけました。 以下のようにmapを使う際に、 mapコンテナの宣言をするのは理解できたのですが、 map<string, int> mmbr ; // (string型,int型)の対データを管理 map<int, int> ikk ; //(int型,int型)の対データを管理 他人が作成したサンプルを見ていたら、 以下のようにmapのコンテナ宣言がされていました。 ********************************************************* typedef KEY key_type; typedef typename std::map<key_type, value_type> container_type; ********************************************************* 1行目でtypedefしているだけなので理解できるのですが、 2行目で行っているmapコンテナの宣言の意味が どうも意味が分からないでいます。 mapコンテナの宣言で、 <string, int>や<int, int>のようにせず、 <key_type, value_type>としているのは、 どういう意味なのでしょうか? どうぞ宜しくお願い致します。

専門家に質問してみよう