如何迭代这张地图?

时间:2011-06-14 07:16:18

标签: c++ compiler-construction map


我有一个函数,其中const std::map<std::string, Array2D<unsigned short>&>* pDataPool是其输入参数之一。函数体中有一段代码片段如下:

std::map<std::string, Array1D<unsigned short>*> DataBuffers;

if (pDataPool != NULL)
{  
   for (std::map<std::string, Array2D<unsigned short>&>::iterator it = pDataPool->begin();
        it != pDataPool->end(); it++)   // Error 
   {    
       std::string sKeyName = it->first;
       DataBuffers[sKeyName] = new Array1D<unsigned short>(2048);
    }
} 

编译器输出:

1>e:\program files\microsoft visual studio 9.0\vc\include\map(168) : error C2529: '[]' : reference to reference is illegal
1>        f:\tips\tips\fy2svsdataiohandler.cpp(77) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
1>        with
1>        [
1>            _Kty=std::string,
1>            _Ty=Array2D<unsigned short> &
1>        ] 
1>f:\tips\tips\fy2svsdataiohandler.cpp(77) : error C2440: 'initializing' : cannot convert from 'std::_Tree<_Traits>::const_iterator to  <br/>'std::_Tree<_Traits>::iterator' 
1>        with
1>        [ 
1>            _Traits=std::_Tmap_traits<std::string,Array2D<unsigned short> &,std::less<std::string>,std::allocator<std::pair<const <br/> std::string,Array2D<unsigned short> &>>,false> 
1>        ] 
1>        No constructor could take the source type, or constructor overload resolution was ambiguous 
1>Build log was saved at "file://f:\Tips\Tips\Debug\BuildLog.htm" 
1>Tips - 2 error(s), 0 warning(s) 
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ========== 

4 个答案:

答案 0 :(得分:2)

看起来pDataPool是不变的。所以你需要使用const_iterator

std::map<std::string, Array2D<unsigned short>&>::const_iterator it = pDataPool->begin()

答案 1 :(得分:1)

请看这里:Why are arrays of references illegal?

您应该使用指针而不是引用。此外,指针还有其他优点:它明确表示数据将被更改。

答案 2 :(得分:1)

for (std::map<std::string, Array2D<unsigned short>&>::iterator it

应该阅读

for (std::map<std::string, Array2D<unsigned short>*>::iterator it

您不能将引用存储在标准容器中; (你可以使用std::ref包装它们,但那是另一天的话题......)。

答案 3 :(得分:0)

已经有了一些答案,但让我总结一下。注意映射类型(这是一个指针!它是1D还是2D?) - 甚至更好,使用typedef来消除你自己:

typedef Array3D<unsigned short> Array; // decide on 1D, 2D, 3D, ...!
typedef std::map<std::string, Array*> ArrayMap;

ArrayMap DataBuffers;

ArrayMap * pDataPool;

/* ... */

if (pDataPool != NULL)
{  
  for (ArrayMap::const_iterator it = pDataPool->begin(), end = pDataPool->end(); it != end; ++it)
  {    
    const std::string & sKeyName = it->first;
    DataBuffers[sKeyName] = new Array(2048); // terrible, use shared_ptr<Array>!
  }
}

注重细节是关键。几点说明:

  • 将原始指针作为映射类型很糟糕;如果元素已经存在并且您只是用new指针覆盖它会怎么样?内存泄漏!您应认真考虑将地图设为std::map<std::string, std::tr1::shared_ptr<Array> >

  • 如果您有大量条目,字符串会导致密钥类型不佳。请考虑使用std::tr1::unordered_map。 (如果您使用的是C ++ 0x或MSVC10,请省略::tr1。)