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

时间:2018-09-19 11:40:26

标签: c++ visual-c++ visual-studio-2013 stl

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

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

当我用这样的代码表达语言时,一切都很好

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

但是,如果我尝试用它做一个衬纸

return insert(object) - begin();

我得到了前面提到的“向量迭代器不兼容”的断言。

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();
}

班级简介:

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也都已就绪。

1 个答案:

答案 0 :(得分:6)

id使迭代器无效。在表达式Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData); vector::insert可以在insert(object) - begin()之前或之后被调用。如果之前调用过,它将被begin()无效。 Order of evaluation

  

几乎所有C ++运算符的操作数求值顺序(包括函数调用表达式中的函数自变量的求值顺序以及任何表达式中子表达式的求值顺序)均未指定。编译器可以按任何顺序求值操作数,并且在再次求同一个表达式时可以选择其他顺序。

当您这样做时:

insert

insert()const_iterator (or auto) it = insert(object); return it - begin(); 之后被调用,因此返回有效的迭代器。