且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C++ std::vector<>::iterator 不是指针,为什么?

更新时间:2021-08-17 01:41:03

你完全正确,vector::iterator 可以通过一个简单的指针来实现(参见 here) -- 事实上,迭代器的概念是基于指向数组元素的指针.但是,对于其他容器,例如 maplistdeque,指针根本不起作用.那么为什么不这样做呢?以下是类实现优于原始指针的三个原因.

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.

  1. 将迭代器实现为单独的类型允许附加功能(超出标准要求的功能),例如(在昆汀评论后的编辑中添加)在取消引用时添加断言的可能性迭代器,例如,在调试模式下.

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