Vector::<int>迭代器与 list::<int>itrator 键在 std::map

vector<int>::iterator versus list<int>::iterator keys in std::map

本文关键字:int gt lt 键在 std map itrator list Vector 迭代器      更新时间:2023-10-16

为什么可以定义 vector::iterator 到 int 的映射,而 list::iterator 到 int 的映射不能?

#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:二进制"<":找不到采用类型为"const std::_List_const_iterator<_Mylist>"的左侧操作数的运算符(或者没有可接受的转换)

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...

cpp首选项文档涵盖了我过去使用旧SGI文档的所有内容,并且仍在更新。看到两者都描述了 RandomAccessIterator 的a<b,而不是双向迭代器概念。

您无法比较任何 T 的std::list<T>迭代器。事实上,只有当两个迭代器都来自同一个向量时,std::vector<T>::iterator才是可比的。

您无法比较std::list迭代器的原因是它效率非常低 - 您必须从其中一个可能走到整个列表的末尾才能找到另一个元素不在它之后。这将是O(N)复杂性,我们不希望像<这样的简单操作。

我不能建议更换,因为我不知道你需要它做什么。因为 std::list 元素的地址是稳定的,所以您可以将这些地址用作map的键。但我看不出这有什么用。