C++ 访问类的成员,该类是 std::map 中的mapped_type

C++ Accessing the members of a class which is the mapped_type in a std::map

本文关键字:map 中的 type std mapped 访问 成员 C++      更新时间:2023-10-16

考虑一个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 – 
std::map内部

将类型存储为std::pairstd::map::find 返回一个iterator。 因此,要访问类的成员,您必须通过 iterator ,它将key_type显示为 firstvalue_type显示为 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;
}

失败,因为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";

最明显的方法是

MyMap[key]->fred

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

也应该工作。 在这两种情况下,都必须确保密钥在使用前存在。 在你编写的代码中,它(通常)不会be,因为您使用的是字符串的特定实例的地址文字作为键;允许编译器将实例与相同的实例合并值,但不是必需的。

问题是迭代器是指针类型,而不是引用类型,因此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";
   }
}