我正在为我的程序编写一个小UI。我有一个方法onMouseMotion(),我可以通过两种方式之一调用它(参见代码);如果我通过std::function调用它,那么std::function循环停止条件中的!=操作符将生成运行时异常vector iterators incompatible。为什么?
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) {}
}更新:
for循环时抛出异常,将发生零次迭代。for循环的相同异常。std::function问题。发布于 2014-05-29 14:49:28
所以很明显
auto为子程序定义迭代器类型,由编译器静态确定(不能在调用之间更改)。child的类型与rbegin()和rend()兼容。child的类型是与rbegin()兼容的关系运算符,但当通过bind()包装器调用时则不兼容。child的类型不能改变,所以在第二种情况下,rend()的类型必须改变。我看到了以下可能性。
this值可能与绑定中捕获的值不同(例如,基类与派生类)。this的值可以通过包装器传递,这会改变它的类型行为。总的来说,这很可能是MSVC的错误。所提供的代码不编译,我不愿意尝试修改,很可能无法重现该bug。如果您可以发布一个repro案例进行编译,我很乐意进一步调查并更新答案。
https://stackoverflow.com/questions/23930602
复制相似问题