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在内部将类型存储为 a std::pair,并且std::map::find,返回 a 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 回答