【问题标题】:Why may vector.begin() not equal to &vector[0]?为什么vector.begin() 不等于&vector[0]?
【发布时间】:2014-07-17 16:18:16
【问题描述】:

这里http://www.parashift.com/c++-faq/vector-is-contiguous.html 声明vector.begin() 可能不等于&vector[0]。为什么会这样定义。是什么阻止vector.begin() 等于&vector[0]

【问题讨论】:

  • vector.begin() 返回一个 vector::iterator,它是一个容器。所以它不仅仅是对第一个元素的引用。
  • 除了答案中提到的原因之外,即使vector 为空,vector.begin() 也是明确定义的。 &vector[0] 不是。
  • @Cyber​​: vector 是一个容器,vector::iterator 是一个类。

标签: c++ vector stl


【解决方案1】:

向量的迭代器可以定义为某个类。由于成员函数返回迭代器,因此它不必是指向数组第一个元素的原始指针。它可以是该类的对象。只需要迭代器定义operator *,它将返回对向量的第一个元素的引用,前提是向量不为空。

【讨论】:

  • 那么,我们可以说&*v.begin() == &v[0] 吗?
  • @Aaron McDaid 是的,我们可以。 *v.begin 返回对前面的引用。
【解决方案2】:

vector.begin() 返回的迭代器在技术上仅允许您通过其上的取消引用运算符获取值。那个取消引用操作符可以在里面做各种各样的事情。大多数实现只是存储一个指向 T 的指针 - 或者 一个指向 T 的指针 - 然后简单地在它们的解引用运算符中解引用它,但这不是迭代器概念的要求。

见:Iterator concept

【讨论】:

    【解决方案3】:

    如果我们有一个类型为 T 的向量

    vector<T> v;

    然后

    v.begin() 的类型与 &v[0] 不同

    v.begin() 的类型为 vector<T>::iterator(如果向量是非常量)或 vector<T>::const_iterator(如果向量是 const)。

    &vector[0] 的类型为 T *

    现在在某些实现中,向量迭代器被实现为指向 T 的指针。 所以一些程序员认为向量迭代器与指向 T 的指针是同义的。 这没有标准的支持。在其他实现中,向量迭代器是一个类。

    要形成一个指向向量中第 N 个元素的迭代器,表达式 应该使用(v.begin() + N)

    要形成一个指向向量中第 N 个元素的指针,表达式 应该使用&v[N]

    无论供应商如何实现向量迭代器,这些表达式都是有效的。 它们也适用于双端队列和字符串。

    【讨论】:

    • 甚至可能是“调试”与“发布”版本中的不同类。编译器供应商可以为调试构建提供某种诊断迭代器,这些迭代器将断言或异常或在无效迭代器使用情况下发生异常。
    • 注意:&v[N]N == v.size()时无效,而v.begin() + N有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 2011-02-01
    • 1970-01-01
    • 2016-05-03
    • 2012-11-11
    • 2013-08-17
    • 1970-01-01
    相关资源
    最近更新 更多