计算两个迭代器之间的距离时,"向量迭代器不兼容"

mar*_*cbf 3 c++ stl visual-c++ visual-studio-2013

我遇到了一个我无法找到原因的问题.

在我的代码中的某个点上,我返回两个std :: vector迭代器之间的距离,一个是对向量的插入操作的结果,另一个是向量的开头.想法是返回新插入对象的索引.

当我说出这样的代码时,一切都很完美

const_iterator (or auto) it = insert(object);
return it - begin();
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试制作一个衬里

return insert(object) - begin();
Run Code Online (Sandbox Code Playgroud)

我得到前面提到的"矢量迭代器不兼容"断言.

begin()实现为:

MyClass::iterator MyClass::begin()
{
  return m_container.begin();
}
Run Code Online (Sandbox Code Playgroud)

和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();
}
Run Code Online (Sandbox Code Playgroud)

课程简介:

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

  ...
  protected:
  std::vector<MyObject*> m_container;
}
Run Code Online (Sandbox Code Playgroud)

为了完整起见

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

我非常想理解断言发生的原因.从我所看到的迭代器是相同的类型,insert()和begin()都在同一个向量上工作.所有必要的typedef也都存在.

Max*_*kin 6

vector::insert使迭代器无效.在表达式中insert(object) - begin() begin()可以在之前或之后调用insert.如果它之前被调用,则它被无效insert().评估顺序:

几乎所有C++运算符的操作数的评估顺序(包括函数调用表达式中函数参数的评估顺序以及任何表达式中子表达式的评估顺序)都未指定.编译器可以按任何顺序计算操作数,并且可以在再次计算相同表达式时选择另一个顺序.

而当你这样做时:

const_iterator (or auto) it = insert(object);
return it - begin();
Run Code Online (Sandbox Code Playgroud)

begin()之后调用insert(),因此返回一个有效的迭代器.