I am writing a small UI for my program. I have the method onMouseMotion()
, which I can call in one of two ways (see code); if I call it through std::function
, then !=
operator in the for loop stop condition produces the run-time exception 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:
for
loop, zero iterations occur.for
loop.std::function
problem.For reference, std::vector::swap does not invalidate iterators.
Iterators are not owning (observing). They are "produced" for a container but are not actually the object that holds the memory. Hence you not only needn't, but also must not delete them.
So it is clear that
auto
defines an iterator type for child, determined statically by the compiler (it cannot change between calls).child
is assignment compatible with rbegin()
and rend()
child
is relational operator compatible with rbegin()
when called directly, but not when called through the bind()
wrapperchild
cannot change, the type of rend()
must have, in the second case.I see the following possibilities.
this
in the first case might be different from that captured in the bind (base class vs derived class, for example)this
may be delivered via a wrapper, which changes its type behaviour.On balance, this is most likely to be an MSVC bug. The code as supplied does not compile and I am reluctant to try to modify and likely not be able to reproduce the bug. If you can post a repro case that compiles, I'd be happy to investigate further and update the answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With