【发布时间】: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);
}
此时让您知道_traces 是std::map<int, TouchTrace> 和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<something> 抛出了异常,我怀疑我应该对此一无所知,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