std :: vector <t> :: iterator可以只是T *吗?

时间:2016-07-22 09:40:03

标签: c++ optimization vector iterator

简单的理论问题:简单的指针是std::vector的有效迭代器类型吗?

对于其他容器(例如list,map),这是不可能的,但对于std::vector,保证数据是连续的,所以我认为没有理由不这样做。

据我所知,某些实现(例如Visual Studio)会对调试版本进行一些安全检查。但这是在UB领域,所以对于定义明确的行为,我认为没有区别。

除了一些检查(&#34;修改&#34;未定义的行为)之外,使用类而不是简单的指针用于向量迭代器有什么好处吗?

3 个答案:

答案 0 :(得分:10)

  

一个简单的指针是std::vector的有效迭代器类型吗?

是。以及std::basic_stringstd::array

  

使用类代替向量迭代器的简单指针有什么好处吗?

它提供了一些额外的类型安全性,因此像下面这样的逻辑错误无法编译:

std::vector<int> v;
int i=0;
int* p = &i;
v.insert(p, 1); // oops, not an iterator!
delete v.begin();  // oops!

std::string s;
std::vector<char> v;
// compiles if string and vector both use pointers for iterators:
v.insert(s.begin(), '?');
std::array<char, 2> a;
// compiles if array and vector both use pointers for iterators:
v.erase(a.begin());

答案 1 :(得分:1)

是的,它可以是T*,但这有一点令人讨厌的属性,与std::vector<int>::iterator的ADL关联的命名空间 std::!因此swap(iter1, iter2)可能无法找到std::swap

答案 2 :(得分:0)

值得深思 - 迭代器类也可以通过索引而不是指针来实现

当然,当向量重新分配时,所有指针,引用和迭代器都会失效。

但至少对于迭代器来说,情况并非总是如此,如果迭代器保存了一个指向向量的索引+指针,则可以创建只返回(*m_vector)[m_index]的非重新分配无效的迭代器。当向量消失或索引无效时,迭代器无效。换句话说,只有当术语vec[i]无效时,迭代器才会无效,无论重新分配如何。

这是向量迭代器的严格非标准实现,但对于基于类的迭代器而不是原始指针而言,这不是一个优势。

另外,UB没有说明在解除引用无效迭代器时应该发生什么。抛出异常或记录错误属于UB。 这意味着执行绑定检查的迭代器明显变慢,但对于速度不重要的某些情况,“安全但速度慢的迭代器”可能比“不安全但快速迭代器”更具优势