简体   繁体   English

为什么我得到错误'vector iterators incompatible'?

[英]Why do I get the error 'vector iterators incompatible'?

I am writing a small UI for my program. 我正在为我的程序编写一个小UI。 I have the method onMouseMotion() , which I can call in one of two ways (see code); 我有方法onMouseMotion() ,我可以用两种方式之一调用它(参见代码); if I call it through std::function , then != operator in the for loop stop condition produces the run-time exception vector iterators incompatible . 如果我通过std::function调用它,则for循环停止条件中的!=运算符会导致运行时异常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 : 更新

  • program is single-threaded. 程序是单线程的。
  • the exception is thrown when entering the for loop, zero iterations occur. 进入for循环时抛出异常,发生零迭代。
  • compiling with MSVC. 用MSVC编译。
  • same exception with an empty for loop. 同样的异常与空for循环。
  • rewritten examples to illustrate the std::function problem. 重写的例子来说明std::function问题。

So it is clear that 所以很明显

  • auto defines an iterator type for child, determined statically by the compiler (it cannot change between calls). auto定义了子的迭代器类型,由编译器静态确定(它不能在调用之间改变)。
  • the type of child is assignment compatible with rbegin() and rend() child类型是与rbegin()rend()兼容的赋值
  • the type of child is relational operator compatible with rbegin() when called directly, but not when called through the bind() wrapper 当直接调用时, child类型是与rbegin()兼容的关系运算符,但在通过bind()包装器调用时则不然
  • since the type of child cannot change, the type of rend() must have, in the second case. 由于child类型不能改变,因此在第二种情况下, rend()的类型必须具有。

I see the following possibilities. 我看到以下可能性。

  1. The vector is a member and therefore the iterator type will be a pointer to member, and pointer to member has some restrictions on how it may be used. 向量是一个成员,因此迭代器类型将是指向成员的指针,指向成员的指针对如何使用它有一些限制。
  2. The value of this in the first case might be different from that captured in the bind (base class vs derived class, for example) 的值this不同于在结合捕获(基类VS派生类,例如)在第一种情况下可能是不同
  3. The value of this may be delivered via a wrapper, which changes its type behaviour. 的值this可以经由一个包装,从而改变它的类型的行为被递送。

On balance, this is most likely to be an MSVC bug. 总的来说,这很可能是一个MSVC错误。 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. 如果你可以发布一个编译的repro案例,我很乐意进一步调查并更新答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM