指向存储在地图容器中的数据的指针

时间:2011-02-16 14:56:08

标签: c++ pointers stl map

我有2张地图,其中一张包含数据

例如

struct DATA {
  int A1;
  int A2;
};
typedef map<int,DATA> DataList;
DataList myData;

我也尝试了以下一些方法:       typedef map<int,DATA*??> DataListPointer;       table<col_name,DataListPointer>;

(注:CC:我真的不明白这一行:

  

地图是一张桌子。列表和指向myData上存在的数据的指针。

或上面正在做什么表 )。

但我想知道如何找到指向地图中存在的数据的指针。我怎么能这样做? 谢谢herzl。

3 个答案:

答案 0 :(得分:3)

您可能需要2次重载:

DATA * lookup( DataList & theMap, int key )
{
   DataList::iterator iter = theMap.find( key );
   if( iter != theMap.end() )
   {
      return &iter->second;
   }
   else
     return NULL;
}

const DATA * lookup( const DataList & theMap, int key )
{
   DataList::const_iterator iter = theMap.find( key );
   if( iter != theMap.end() )
   {
      return &iter->second;
   }
   else
     return NULL;
}

当然这意味着重复代码。所以可能是const-cast的好候选人。

DATA * lookup( DataList & theMap, int key )
{
   return const_cast<DATA *>(lookup( const_cast<const DataList&>(theMap), key));
}

您可以将其设为通用模板:

template< typename Key, typename Value >
const Value * mapValueLookup( const std::map<Key, Value>& theMap, Key key )
{
   typename std::map<Key, Value>::const_iterator iter = theMap.find(key);
   if( iter != theMap.end() )
   {
      return &iter->second;
   }
   else
     return NULL;
}

template< typename Key, typename Value >
Value * mapValueLookup( std::map<Key, Value>& theMap, Key key )
{
   return const_cast<Value*>( mapValueLookup
       ( const_cast<const std::map<Key, Value> &>(theMap),
       key ) );
}

答案 1 :(得分:0)

这将获得指向地图中DATA值的指针(如果存在)。

   DataList::iterator it = myData.find( 42 );
   DATA * pData = NULL;       
   if ( it != myData.end() ) {
          pData = &((*it).second);
   }

答案 2 :(得分:0)

鉴于您的定义(完全足够),正如已经指出的那样,您的地图由 std::pair<int, DATA> 元素组成,以某种方式串在一起(红黑树,一般来说,对于有序的 {{1} })。迭代器为您提供该映射中的位置,其行为类似于指向元素的指针。特别是,取消引用一个有效的会得到 std::map,你的键在 std::pair 中,你的数据在 .first 中。但是,您将 .second 用作“无有效内容”迭代器值,而不是 nullptr。因此,map.end() 为您提供迭代器,该迭代器保存 map.find(key) 等于您的 .first(如果找到)或迭代器值 key 否则的位置。

之前的帖子提供了很好的解决方案。我认为极简的通用解决方案如下所示:

map.end()

适用于可变映射和常量映射。

所以,如果您有以下情况:

// return a pointer to the map's mapped_type value associated with the key;
// if the key is not found, return nullptr.
template <class Map, typename Key>
auto mapLookup(Map&& map, Key&& key)
{
  auto iter = map.find(key);
  return iter != map.end() ? &iter->second : nullptr;
}

你可以做到

DataList myData;
//...
myData[1] = DATA{ 2, 3 };
//...

遗憾的是,此功能无法在标准(非多)地图类型中立即可用。 C++20 添加了一个 DATA* pointer1 = mapLookup(myData, 1); assert (pointer1 != nullptr); // we expect to find myData assert (pointer1 == &myData[1]); // it should be the same as indexed access assert (pointer1->A1 == 2); // and should find the values we inserted assert (pointer1->A2 == 3); DATA* pointer2 = mapLookup(myData, 999); // a key we haven't used assert (pointer2 == nullptr); // so we could not find it 方法,这很好,但是如果它返回了一个指向该值的指针(或一个 bool contains(const Key& key) const?),它将允许相同的功能(您可以测试指针的带有 std::optional<std::reference_wrapper<mapped_type>>> 的 null 性就像 !) 以及提供对数据的直接访问(如果存在)。