2014-01-09 82 views
5

我正在實現一個映射作爲我的硬件分配的一部分。該地圖應該支持兩種類型的迭代器:錯誤類型的迭代器使用

  • 迭代器 - 允許更改地圖。
  • constant_iterator - 不允許更改地圖。

我有以下幾種方法:

Map::const_iterator begin() const; 
Map::const_iterator end() const; 
Map::iterator begin(); 
Map::iterator end(); 

但是當我測試的實現用下面的代碼:

for(Map<std::string,int>::const_iterator it = msi.begin(); it != msi.end(); ++it) { 
    std::cout << *it << std::endl; 
} 

我得到以下問題:

map_test.cpp:49:43: error: no viable conversion from 'Map<basic_string<char>, int>::iterator' to 'Map<std::string, int>::const_iterator' 
     for(Map<std::string,int>::const_iterator it = msi.begin(); it != msi.end(); ++it) { 
               ^ ~~~~~~~~~~~ 
./map_new.h:57:3: note: candidate constructor not viable: no known conversion from 'Map<basic_string<char>, int>::iterator' to 'const 
     Map<basic_string<char>, int>::const_iterator &' for 1st argument 
       const_iterator(const Map<KeyType, DataType>::const_iterator& sIterator): 
       ^

這意味着編譯器選擇錯誤的開始/結束m編制方法。

我該如何解決這個問題?

回答

11

通過提供從iteratorconst_iterator的隱式轉換。您可以通過給const_iterator構建一個iterator或通過爲iterator提供const_iterator轉換運算符來完成此操作。

,當你做這種事情這種方法在標準庫中使用:

std::vector<int> v; 
std::vector<int>::const_iterator it = v.begin(); 

在C++ 11,你有一些直接返回const_iterators,即使對於非const實例的方法。但這些都需要一個不同的名稱,因爲你不能返回類型超載:

std::vector<int> v; 
std::vector<int>::const_iterator it = v.cbegin(); 
+0

但是,這隻會繞過問題,不是嗎? –

+0

@Doppelganger不,它應該解決問題。這是標準庫容器中發生的情況。 – juanchopanza

+0

它確實解決了這個問題,謝謝。 [我確信存在更優雅的解決方案] –

2

您還可以創建cbegin()cend()成員函數將返回常量迭代器。

+0

您忘記添加cbegin/cend以C++ 11標準到達,並且不適用於早期編譯器。 –

+0

TS實現了他自己的Map類,所以他可以選擇他喜歡的任何名字 – nikitoz

+2

@Sergey無關緊要,因爲這些函數將在自定義類中定義 – vershov

2

您有幾個選項可以避免此問題。

  1. 使用iterator而不是常量性 「for」 循環
  2. 這樣定義下列對象:

    const Map<string, int> msi; 
    
  3. 你的迭代器類定義運營商地圖轉換::爲const_iterator到地圖::迭代器