【问题标题】:Pointer to data that stored in a map container指向存储在地图容器中的数据的指针
【发布时间】:2011-02-16 14:56:07
【问题描述】:

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

例如

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

我还尝试了以下一些方法: typedef map&lt;int,DATA*??&gt; DataListPointer; table&lt;col_name,DataListPointer&gt;;

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

地图是一个表格。 myData 上存在的列和指向数据的指针列表。

或者上面的表在做什么 )。

但我想知道如何获取指向地图中存在的数据的指针。我该怎么做? 谢谢赫兹。

【问题讨论】:

  • 你能举个具体的例子说明你想做什么吗?
  • 我的数据存在于一个类中,我不想将它复制到其他范围。我只想发送指向数据的表结构。
  • @closers 我认为那里有一个合理的问题,只是需要一些编辑。

标签: c++ pointers stl map


【解决方案1】:

您可能需要 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 ) );
}

【讨论】:

    【解决方案2】:

    这将获取指向映射中的 DATA 值的指针(如果存在)。

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

    【讨论】:

      【解决方案3】:

      鉴于您的定义(完全足够),正如已经指出的那样,您的地图由 std::pair&lt;int, DATA&gt; 元素组成,以某种方式串在一起(红黑树,通常是有序的 std::map)。迭代器为您提供该映射中的位置,其行为类似于指向元素的指针。特别是,取消引用一个有效的会给出std::pair,您的密钥在.first,您的数据在.second。但是,您将map.end() 用作“无有效内容”迭代器值,而不是nullptr。因此,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 };
      //...
      

      你可以的

      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
      

      遗憾的是,此功能在标准(非多)地图类型中无法立即使用。 C++20 添加了一个 bool contains(const Key&amp; key) const 方法,这很好,但如果它返回了一个指向该值的指针(或一个 std::optional&lt;std::reference_wrapper&lt;mapped_type&gt;&gt;&gt;?),它将允许相同的功能(您可以使用! 就像 bool) 以及提供对数据的即时访问(如果存在)。

      【讨论】:

        猜你喜欢
        • 2014-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-21
        • 1970-01-01
        • 2011-02-18
        • 1970-01-01
        相关资源
        最近更新 更多