首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我得到错误‘向量迭代器不相容’?

为什么我得到错误‘向量迭代器不相容’?
EN

Stack Overflow用户
提问于 2014-05-29 09:57:03
回答 1查看 567关注 0票数 7

我正在为我的程序编写一个小UI。我有一个方法onMouseMotion(),我可以通过两种方式之一调用它(参见代码);如果我通过std::function调用它,那么std::function循环停止条件中的!=操作符将生成运行时异常vector iterators incompatible。为什么?

代码语言:javascript
复制
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循环时抛出异常,将发生零次迭代。
  • 用MSVC编译。
  • for循环的相同异常。
  • 重写示例来说明std::function问题。
EN

回答 1

Stack Overflow用户

发布于 2014-05-29 14:49:28

所以很明显

  • auto为子程序定义迭代器类型,由编译器静态确定(不能在调用之间更改)。
  • child的类型与rbegin()rend()兼容。
  • 当直接调用时,child的类型是与rbegin()兼容的关系运算符,但当通过bind()包装器调用时则不兼容。
  • 因为child的类型不能改变,所以在第二种情况下,rend()的类型必须改变。

我看到了以下可能性。

  1. 向量是成员,因此迭代器类型将是成员的指针,而指向成员的指针对如何使用它有一些限制。
  2. 第一种情况下的this值可能与绑定中捕获的值不同(例如,基类与派生类)。
  3. this的值可以通过包装器传递,这会改变它的类型行为。

总的来说,这很可能是MSVC的错误。所提供的代码不编译,我不愿意尝试修改,很可能无法重现该bug。如果您可以发布一个repro案例进行编译,我很乐意进一步调查并更新答案。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23930602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档