Why do I get "vector error iterators" incompatible?

I am writing a small user interface for my program. I have an onMouseMotion() method, which I can name in one of two ways (see Code); if I call it via std::function , the != operator in loop stop mode throws an exception at runtime vector iterators incompatible . Why?

 class Widget : public EventHandler { protected: /* ... */ std::vector<Widget *> children_; std::function<bool(Event &)> func_; private: bool onMouseMotion(Event &event); /* ... */ }; Widget::Widget() { /* ... */ func_ = std::bind(&Widget::onMouseMotion, this, std::placeholders::_1); /* ... */ } bool Widget::processEvent(Event &event) { if (event.getType() == ui::EventType::MouseMotionEvent) { /* Method 1 - onMouseMotion works ok */ onMouseMotion(event); /* Method 2 - onMouseMotion throws */ //func_(event); return true; } } bool Widget::onMouseMotion(Event &event) { /* exception occurs on the next line, only when using Method 2 above */ for (auto child = children_.rbegin(); child != children_.rend(); ++child) {} } 

Updates :

  • The program is single-threaded.
  • an exception occurs when you enter a for loop, zero iterations occur.
  • compilation with MSVC.
  • same exception with empty for loop.
  • rewritten examples to illustrate the std::function problem.
+7
c ++ iterator vector visual-c ++ std-function
source share
1 answer

So it’s clear that

  • auto determines the type of iterator for the child, defined statically by the compiler (it cannot change between calls).
  • type child is an assignment compatible with rbegin() and rend()
  • type child is a relational operator compatible with rbegin() when called directly, but not when called through the bind() wrapper
  • since the type of child cannot change, the type of rend() must have in the second case.

I see the following possibilities.

  • A vector is a member, and therefore, the type of the iterator will be a pointer to a member, and a pointer to a member has some limitations on how it can be used.
  • The value of this in the first case may differ from the value specified in the binding (for example, the base class and the derived class)
  • This value can be delivered through a shell that changes its type behavior.

In general, most likely this is an MSVC error. The code in the bundle does not compile, and I do not want to try to modify it and probably am not able to reproduce the error. If you can post a resulting case that compiles, I would be happy to continue researching and updating the answer.

+2
source share

All Articles