2012-10-06 35 views
3

爲什麼可以定義vector :: iterator映射到int,但是list :: iterator映射到int不能?vector <int> ::迭代器與列表<int> :: std :: map中的迭代器鍵

#include <vector> 
#include <list> 
#include <map> 
#include <algorithm> 
using namespace std; 


int main() 
{ 
    int ia[] = {1,2,3,4,5,6,7,8,9,0}; 

    vector<int> v(begin(ia), end(ia)); 
    auto it1 = find(begin(v), end(v), 4); 
    map< vector<int>::const_iterator, int > m1; 
    m1.insert(map<vector<int>::const_iterator, int>::value_type(it1,*it1)); 

    list<int> l(begin(ia), end(ia)); 
    auto it2 = find(begin(l), end(l),5); 
    map< list<int>::const_iterator, int> m2; 
    m2.insert(map<list<int>::const_iterator, int>::value_type(it2,*it2)); //doesn't compile 

} 

錯誤1錯誤C2678:二進制 '<':沒有操作員發現這需要類型的左邊的操作數 '常量性病:: _ List_const_iterator < _Mylist>'(或沒有可接受轉換)

+0

什麼是錯誤? – Useless

+0

錯誤錯誤C2678:二進制'<':沒有找到操作符,它需要類型'const std :: _ List_const_iterator <_Mylist>'的左手操作數(或沒有可接受的轉換) – hhbilly

+0

這應該是在問題中我已經添加了它)。出於興趣,是在'm2.insert'行還是m2的_declaration_? – Useless

回答

5

std::map要求的關鍵是可比較,無論是與<,或所提供的比較器。

概念,隨機訪問迭代器相媲美,但雙向迭代器都沒有。 std::vector迭代器是隨機訪問的,而迭代器是std::list是雙向的。

所以,你的列表迭代器不滿足std::map密鑰類型的可比性要求。如果你提供一個比較器,可以有效地決定哪些std::list::const_iterator應該在另一個之前來了,你可以將它傳遞到地圖中,這將正常工作。草圖:

struct ListIterCmp { 
    bool operator() (list<int>::const_iterator a, list<int>::const_iterator b) 
    { 
     // how? 
    } 
}; 
map< list<int>::const_iterator, int, ListIterCmp> m2; 
// this should work now... 

cppreference文檔包括我以前用舊SGI文檔的一切,並且還在更新。看到這兩個描述a<b爲RandomAccessIterator,而不是爲BidirectionalIterator概念。

+0

的確如懷疑。感謝鏈接列出所有允許的表達式。雙向迭代器不支持<,>,<=,> =當然,因爲它們可以在任一方向上遞增,因此違反了關鍵類型中嚴格的弱排序。 – hhbilly

+0

這[cplusplus.com](http://www.cplusplus.com/reference/std/iterator/)文件似乎稍好一些。 – hhbilly

4

std::list<T>任何T.你不能比較迭代事實上,如果有問題迭代器都來自同一矢量std::vector<T>::iterator是唯一能媲美。

0

迭代器不能比較std::list的原因是它會非常低效 - 您必須從其中一個走到可能的整個列表的末尾,以便找到另一個元素不在其後面。這將是O(N)的複雜性,我們不希望像<這樣的簡單操作。

我不能提出一個替代品,因爲我不知道你需要它。由於std::list的元素地址是穩定的,因此您可以將地址用作map的密鑰。但是我沒有看到這會如何有用。

相關問題