"Vector Iterators Incompatible" 计算两个迭代器之间的距离时

"Vector Iterators Incompatible" when calculating distance between two iterators

我遇到了一个问题,我无法完全找到原因。

在我的代码中的某个点,我 return 计算两个 std::vector 迭代器之间的距离,一个是向量插入操作的结果,另一个指向开始的向量。思路是return新插入对象的索引

当我这样表述代码时,一切都完美无缺

const_iterator (or auto) it = insert(object);
return it - begin();

但是,如果我尝试用它制作一个衬垫

return insert(object) - begin();

我得到前面提到的 "Vector Iterators Incompatible" 断言。

begin() 实现为:

MyClass::iterator MyClass::begin()
{
  return m_container.begin();
}

并且 insert() 实现为:

MyClass::iterator MyClass::insert(MyObject *object)
{
  if (object)
  {
    const_iterator it = std::lower_bound(begin(), end(), object, DereferencedLess<MyObject >());

    if (it == end() || *(*it) != *object)
      return m_container.insert(it, object);
  }

  return end();
}

class的简要概述:

MyClass {
  ...
  iterator  begin();
  const_iterator begin() const;
  iterator  insert(MyObject*);

  ...
  protected:
  std::vector<MyObject*> m_container;
}

为了完整起见

template<typename T>
struct DereferencedLess
{ inline bool operator()(const T *p1, const T *p2) const { return *p1 < *p2; } };

我非常想了解为什么会出现这种断言。据我所见,迭代器属于同一类型,并且 insert() 和 begin() 都在同一个向量上工作。所有必要的 typedef 也已到位。

vector::insert 使迭代器无效。在表达式 insert(object) - begin() 中,可以在 insert 之前或之后调用 begin()。如果它之前被调用过,它会被 insert() 无效。 Order of evaluation:

Order of evaluation of the operands of almost all C++ operators (including the order of evaluation of function arguments in a function-call expression and the order of evaluation of the subexpressions within any expression) is unspecified. The compiler can evaluate operands in any order, and may choose another order when the same expression is evaluated again.

而当您这样做时:

const_iterator (or auto) it = insert(object);
return it - begin();

begin()insert() 之后调用,因此 returns 是一个有效的迭代器。