C++ std::vector<>::iterator 不是指针,为什么?
只是简单的介绍,用简单的话.在 C++ 中,迭代器是事物",您至少可以在其上编写解引用运算符 *it
、增量运算符 ++it
,对于更高级的双向迭代器,递减 --it
,最后但同样重要的是,对于随机访问迭代器,我们需要运算符索引 it[]
以及可能的加法和减法.
Just a little introduction, with simple words.
In C++, iterators are "things" on which you can write at least the dereference operator *it
, the increment operator ++it
, and for more advanced bidirectional iterators, the decrement --it
, and last but not least, for random access iterators we need operator index it[]
and possibly addition and subtraction.
C++ 中的此类事物"是具有相应运算符重载的类型的对象,或简单明了的指针.
Such "things" in C++ are objects of types with the according operator overloads, or plain and simple pointers.
std::vector<>
是一个包装连续数组的容器类,因此指针作为迭代器是有意义的.在网上和一些文献中,您可以找到用作指针的 vector.begin()
.
std::vector<>
is a container class that wraps a continuous array, so pointer as iterator makes sense. On the nets, and in some literature you can find vector.begin()
used as a pointer.
使用指针的基本原理是开销更少,性能更高,特别是如果优化编译器检测到迭代并执行它的事情(向量指令和其他东西).对于编译器来说,使用迭代器可能更难优化.
The rationale for using a pointer is less overhead, higher performance, especially if an optimizing compiler detects iteration and does its thing (vector instructions and stuff). Using iterators might be harder for the compiler to optimize.
知道了这一点,我的问题是为什么现代 STL 实现,比如说 MSVC++ 2013 或 Mingw 4.7 中的 libstdc++,使用向量迭代器的特殊类?
Knowing this, my question is why modern STL implementations, let's say MSVC++ 2013 or libstdc++ in Mingw 4.7, use a special class for vector iterators?
推荐答案
你完全正确,vector::iterator
可以通过一个简单的指针来实现(参见 here) -- 事实上,迭代器的概念是基于指向数组元素的指针.但是,对于其他容器,例如 map
、list
或 deque
,指针根本不起作用.那么为什么不这样做呢?以下是类实现优于原始指针的三个原因.
You're completely correct that vector::iterator
could be implemented by a simple pointer (see here) -- in fact the concept of an iterator is based on that of a pointer to an array element. For other containers, such as map
, list
, or deque
, however, a pointer won't work at all. So why is this not done? Here are three reasons why a class implementation is preferrable over a raw pointer.
将迭代器实现为单独的类型允许附加功能(超出标准要求的功能),例如(在昆汀评论后的编辑中添加)在取消引用时添加断言的可能性迭代器,例如,在调试模式下.
Implementing an iterator as separate type allows additional functionality (beyond what is required by the standard), for example (added in edit following Quentins comment) the possibility to add assertions when dereferencing an iterator, for example, in debug mode.
重载解析 如果迭代器是指针T*
,它可以作为有效参数传递给采用T*
,而这对于迭代器类型是不可能的.因此,使 std::vector<>::iterator
成为指针实际上会改变现有代码的行为.例如,考虑
overload resolution If the iterator were a pointer T*
, it could be passed as valid argument to a function taking T*
, while this would not be possible with an iterator type. Thus making std::vector<>::iterator
a pointer in fact changes the behaviour of existing code. Consider, for example,
template<typename It>
void foo(It begin, It end);
void foo(const double*a, const double*b, size_t n=0);
std::vector<double> vec;
foo(vec.begin(), vec.end()); // which foo is called?
依赖于参数的查找(ADL;由 juanchopanza 指出)如果您进行了不合格的调用,ADL 会确保仅搜索 namespace std
中的函数如果参数是在 namespace std
中定义的类型.所以,
argument-dependent lookup (ADL; pointed out by juanchopanza) If you make an unqualified call, ADL ensures that functions in namespace std
will be searched only if the arguments are types defined in namespace std
. So,
std::vector<double> vec;
sort(vec.begin(), vec.end()); // calls std::sort
sort(vec.data(), vec.data()+vec.size()); // fails to compile
如果 vector<>::iterator
只是一个指针,则找不到
std::sort
.
std::sort
is not found if vector<>::iterator
were a mere pointer.
相关文章