2

を考えてみましょうstd::map<const char *, MyClass*>

MyClassマップが指すオブジェクトのメンバー(変数または関数)にアクセスするにはどうすればよいですか?

// assume MyClass has a string var 'fred' and a method 'ethel'
std::map<const char*, MyClass*> MyMap;

MyMap[ "A" ] = new MyClass;
MyMap.find( "A" )->fred = "I'm a Mertz";  // <--- fails on compile
MyMap.find( "A" )->second->fred = "I'm a Mertz";  // <--- also fails

編集-Xeoの提案による

ダミーコードを投稿しました。これが実際のコードです。

// VarInfo is meta-data describing various variables, type, case, etc.
std::map<std::string,VarInfo*> g_VarMap; // this is a global 

int main( void )
{ 
   // ........ g_VarMap["systemName"] = new VarInfo; 
   g_VarMap.find( "systemName" ).second->setCase( VarInfo::MIXED, VarInfo::IGNORE ); 
   // ..... 
} 

エラーは次のとおりです。

struct std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, VarInfo*> >’ has no member named ‘second’
Field 'second' could not be resolved Semantic Error make: *** [src/ACT_iod.o] Error 1 C/C++ Problem
Method 'setCase' could not be resolved Semantic Error – 
4

4 に答える 4

8

std::mapは型を として内部的に格納しstd::pair、 は をstd::map::find返しますiterator。したがって、クラスのメンバーにアクセスするにiteratorは、key_typeasfirstvalue_typeasを表す を経由する必要がありますsecond。また、他の人が述べているように、おそらくとして使用しないconst char*でくださいkey_type。ここに短い例があります。

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

struct T
{
   T(int x, int y) : x_(x), y_(y)
   {}

   int x_, y_;
};

int main()
{
   typedef std::map<std::string, T> map_type;
   map_type m;

   m.insert(std::make_pair("0:0", T(0,0)));
   m.insert(std::make_pair("0:1", T(0,1)));
   m.insert(std::make_pair("1:1", T(1,1)));

   // find the desired item (returns an iterator to the item
   // or end() if the item doesn't exist.
   map_type::const_iterator t_0_1 = m.find("0:1");

   if(m.end() != t_0_1)
   {
      // access via the iterator (a std::pair) with 
      // key stored in first, and your contained type
      // stored in second.
      std::cout << t_0_1->second.x_ << ':' << t_0_1->second.y_ << '\n';
   }

   return 0;
}
于 2012-06-29T14:32:56.190 に答える
2

std::map<T, Y>::find()MyMap オブジェクトへの参照ではなく、反復子を返すため、失敗します。正しいコードは次のようになります。

map<const char*, MyClass*>::iterator a;
a = MyMap.find("A");
// a->fred; this is wrong too
a->second->fred = "Whatever";
于 2012-06-29T14:31:20.383 に答える
1

一番分かりやすい方法は

MyMap[key]->fred

、 しかし

MyMap.find( key )->second->fred

も動作するはずです。どちらの場合も、使用する前にキーが存在することを確認する必要があります。あなたが書いたコードでは、文字列リテラルの特定のインスタンスのアドレスをキーとして使用しているため、(通常は) そうではありません。コンパイラは同じ値のインスタンスをマージできますが、必須ではありません。

于 2012-06-29T14:32:52.657 に答える
1

問題は、反復子が参照型ではなくポインター型であるため、iter.secondコンパイルに失敗することです。

iter->second代わりに、ポインター構文(ドットの代わりに矢印) を使用する必要があります。

次の短い例を考えてみましょう。

#include <iostream>
#include <map>

int main()
{
   std::map<int, std::string> myMap;

   std::map<int, std::string>::iterator it;
   std::map<int, std::string>::iterator end = myMap.end();

   myMap.insert(std::pair<int, std::string>(0, "hello"));
   myMap.insert(std::pair<int, std::string>(1, "world"));

   for(it = myMap.begin(); it != end; ++it)
   {
      // std::cout << "Value: " << it.second << "\n";
      // The previous line will fail to compile with error:
      //    ‘struct std::_Rb_tree_iterator<std::pair<const int,
      //    std::basic_string<char, std::char_traits<char>,
      //    std::allocator<char> > > >’ has no member named ‘second’

      // The following line is correct
      std::cout << "Value: " << it->second << "\n";
   }
}
于 2014-07-10T15:16:46.217 に答える