2011-06-14 119 views
2


我有一個函數,其中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 ========== 
+0

在代碼segement,第一行應爲:的std ::地圖<的std :: string,Array1D <無符號短> *>數據緩衝區; – GoldenLee 2011-06-14 07:19:16

+0

對不起,我不知道如何擺脫SO中使用的特殊字符「<" and ">」。所以,我寫了一個醜陋的字符串const std :: map'<'std :: string,Array2D'''unsigned short'>'&'>'* pDataPool。它應該是const std :: map &> * pDataPool。 – GoldenLee 2011-06-14 07:24:11

+0

有一個標題爲「格式」的巨大面板出現在您寫問題的空間旁邊。閱讀! – 2011-06-14 07:30:18

回答

1

看看這裏:Why are arrays of references illegal?

您應該使用指針而不是引用。指針還有其他的好處:它明確指出數據將被改變。

+0

原始*數據可能會被改變。 – 2011-06-14 07:32:04

+0

謝謝。我訪問了該鏈接。實際上,它不能通過「for」循環。 – GoldenLee 2011-06-14 07:36:37

+0

而且爲什麼STL容器不能容納引用:http://stackoverflow.com/questions/1543193/why-cant-i-store-references-in-an-stl-map-in-c – nimrodm 2011-06-14 07:37:40

2

看起來像pDataPool是恆定的。所以,你需要使用const_iterator

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

我曾經有過使用const_iterator的情況。但它無法解決問題。 – GoldenLee 2011-06-14 07:32:43

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

應該讀

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

你可能不存儲在一個標準集裝箱的引用; (你可以使用std::ref來包裝它們,但那是另一天的話題......)。

+0

親愛的Tomalak Geret'kal 也許你是對的。我通過引用std :: map &>將所有參數列表更改爲std :: map *>指針引用。我的程序現在通過編譯。爲什麼我用std :: ref包裝Array2D ?你今天能對這個話題有所瞭解嗎?再次感謝你! – GoldenLee 2011-06-14 07:52:29

+0

@GoldenLee:請使用「@name」語法生成SO通知。 – 2011-06-14 15:37:57

+0

@GoldenRef:你爲什麼?你沒有。我很困惑。你的意思是「指針」而不是「指針參考」。 – 2011-06-14 15:38:37

0

已經有了一些答案,但讓我總結一下。 (!?這是一個指針,是一維或二維)注意映射類型 - 甚至更好,使用typedef來deconfuse自己:

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。)