【问题标题】:yet another map/set iterator not incrementable, but this time it's C++11另一个 map/set 迭代器不可递增,但这次是 C++11
【发布时间】:2013-06-17 11:47:45
【问题描述】:

这是我宝贵的一小段代码,让我的 VC++ 2012 不寒而栗,而如果我在 Mac 上运行相同的代码,似乎完全没有问题。

for(auto trace : _traces) {
    std::list<tuio::Cursor> cursors = trace.second.cursors;

    std::vector<Vec2f> v;
    for(tuio::Cursor p : cursors) {
        v.push_back(p.getPos());
    }
    if(v.size() > 2) {
        BSpline2f l(v, min((int)v.size()-1, 3), false, true);
        PolyLine2f pl;
        for(int i = 0; i < v.size(); i++) {
            float t = (float)i/(float)v.size();
            pl.push_back((l.getPosition(t)*s)+o);
        }
        gl::draw(pl);
    }


    tuio::Cursor c = cursors.back();
    gl::drawSolidCircle((c.getPos()*s)+o , _scale * 10.0f);
}

此时让您知道_tracesstd::map&lt;int, TouchTrace&gt;TouchTrace 是我定义的一个类是有意义的,它基本上是tuio::Cursor 列表的容器加上一些额外的功能。我认为这个问题无关紧要,特别是因为成员是公开的,我直接与他们打交道,所以你可以在这个 sn-p 中有效地看到我所有的脏衣服。

问题是我随机得到一个“map/set iterator not incrementable”异常,尤其是当我有点疯狂并绘制很长的轨迹时(但有时会在较短的轨迹上发生粪便,这就是随机事物的问题)。另外,只有当我将手指从桌面上移开时才会发生这种情况(你明白了),我在这里执行这段漂亮的小代码:

void TheApp::cursorRemoved(tuio::Cursor cursor) {
    _traces[cursor.getSessionId()].addCursorUp(cursor);
    _traces.erase(cursor.getSessionId());
    // Well, that was abrupt.
}

注意注释,以防万一你需要用硬棍子打我,如果问题是这个主线程和绘图线程之间的某种奇怪的交叉运行。在这一点上,让您知道我正在使用 libCinder 可能很重要,尽管我对它的内部知之甚少,所以我只能推测应用程序和绘图在不同的线程中运行。无论如何。

回溯发现for 在第一行,当然std::_Tree_const_iterator&lt;something&gt; 抛出了异常,我怀疑我应该对此一无所知,Jon Snow。 auto 的东西似乎工作正常,或者至少 VS 是这样告诉我的,所以我认为 foreach 构造有问题,并用显式迭代器等重写​​了它。

我错了。接下来,我将 auto 更改为它们的显式类型,但没有任何改进。好吧,不是真的,因为在某些时候我遇到了一个不同的异常,关于列表迭代器不兼容的问题,这就是为什么我扔掉自动并硬编码实际类型的原因。

虽然此时我有效地使用了普通的旧 C++03 技术,但其余代码仍被 VS 2012 编译为 C++11,这在处理切割时并不完全可靠边缘技术(事实上,我上次检查时,也就是六个月前,它甚至不支持基于范围的 for 循环)。

任何想法表示赞赏。

【问题讨论】:

  • 没有宝贵的代码,您需要在运行代码之前对其进行编译;),所以您可能没有准确地提出您的问题,而只是在咆哮。您可能正在使用来自临时对象的迭代器。你调试过吗?哪条线路崩溃了?
  • 谁说我没有编译?每次按 F5,我实际上就失去了三十秒的生命! :) 因此,我也不在咆哮。我向您保证,如果我在咆哮,您将看不到任何一行代码;)现在,至于您评论的严肃部分,这很可能,但据我所知,我不是。据我所知,我正在复制所有内容(虽然不是很多,但仍然如此)。
  • 当然,在不编译的情况下运行它会非常困难:)。循环呢(见下面我的回答)。您可能在迭代时修改了地图
  • 如果您有多个线程同时访问_traces,并且其中至少一个线程调用了非常量方法(特别是operator[]std::map 上是非常量)这是一场数据竞赛:未定义的行为。你会过得很糟糕的。

标签: list visual-studio-2012 c++11 map iterator


【解决方案1】:

如果您在循环 for(auto trace : _traces) { 中从 _traces 中删除光标,则循环迭代器将失效

【讨论】:

  • 是的,这完全有可能。事实上,我从第二个 sn-p 中注释掉了擦除,并且我设法在很长一段时间内没有崩溃。一种可行的方法可能是在 TouchTrace 中有一个 isVisible 成员,将其设置为 false 以防止它被绘制(等待对绘制代码的修改),并在短暂的延迟后将其删除。
  • 这里有个类似的问题:stackoverflow.com/questions/17230779/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 2010-09-16
  • 2013-03-23
相关资源
最近更新 更多