我需要知道我是否可以减少迭代器并拥有一个有效的对象。以下错误因为我将迭代器减少1而不存在。我怎么知道所以我没有得到错误?
ticks.push_front(Tick(Vec3(0, 0, 5), 0));
ticks.push_front(Tick(Vec3(0, 0, 8), 100));
ticks.push_front(Tick(Vec3(0, 0, 10), 200));
bool found = false;
list<Tick, allocator<Tick>>::iterator iter;
for (iter = ticks.begin(); iter != ticks.end(); ++iter)
{
Tick t = (*iter);
if (214>= t.timestamp)
{
prior = t;
if (--iter != ticks.end())
{
next = (*--iter);
found = true;
break;
}
}
}
我正在尝试直接在“上方”找到条目,并直接在“下方”列表中的值214。如果只有1存在那么我不在乎。我需要在上面和下面存在。
答案 0 :(得分:1)
在您对问题进行编辑后,我认为我可以写出比以前更好的答案。
首先,为使用其时间戳的Tick
编写一个比较函数:
bool CompareTicks(const Tick& l, const Tick& r)
{
return l.timestamp < r.timestamp;
}
现在使用std::upper_bound
的函数:
// Get an iterator pointing to the first element in ticks that is > 214
// I'm assuming the second parameter to Tick's ctor is the timestamp
auto itAbove = std::upper_bound(ticks.begin(), ticks.end(), Tick(Vec3(0, 0, 0), 214), CompareTicks);
if(itAbove == ticks.end())
; // there is nothing in ticks > 214. I don't know what you want to do in this case.
这将为您提供刻度线中的第一个元素&gt; 214.接下来,您可以使用lower_bound
查找第一个元素&gt; = 214:
// get an iterator pointing to the first element in ticks that is >= 214
// I'm assuming the second parameter to Tick's ctor is the timestamp
auto itBelow = std::lower_bound(ticks.begin(), ticks.end(), Tick(Vec3(0, 0, 0), 214), CompareTicks);
你现在必须用itBelow
做一个额外的步骤才能获得214之前的第一个元素,注意不要超过列表的开头:
if(itBelow == ticks.begin())
; // there is nothing in ticks < 214. I don't know what you want to do in this case.
else
--itBelow;
现在,假设您没有遇到任何错误情况,itAbove
指向第一个元素&gt; 214,itBelow
指向最后一个元素&lt; 214。
这假定您的Tick
按时间顺序排列,这似乎就是这种情况。另请注意,即使列表中有多个214,此技术也能正常工作。最后,你说这个列表很短,所以它并不值得担心时间复杂度,但如果你还用list
代替vector
,这种技术可以让你获得对数性能迭代方法的线性。
答案 1 :(得分:1)
您的核心问题的答案很简单。如果你在最后,不要增加。如果你刚开始就不要减少。
在递增之前,请检查。
if ( iter == ticks.end() )
在降级之前,请检查。
if ( iter == ticks.begin() )
您的特定示例
看看你想要完成什么,我怀疑你打算使用:
if (iter != ticks.begin())
而不是
if (--iter != ticks.end())
<强>更新强>
您似乎依赖于按时间戳排序的列表内容。
在您发表评论后,我认为您需要的是:
if (214>= t.timestamp)
{
prior = t;
if (++iter != ticks.end())
{
next = *iter;
if ( 214 <= next.timestep )
{
found = true;
break;
}
}
}
更新2
我同意@crashmstr的评论。你的逻辑可以是:
if (214 <= t.timestamp)
{
next = t;
if ( iter != ticks.begin())
{
prior = *--(iter);
found = true;
break;
}
}
答案 2 :(得分:1)
我认为您可以使用标准库std::adjacent_find
中的<algorithm>
执行所需操作。默认情况下,std::adjacent_find
会查找两个连续的相同的元素,但您可以提供自己的函数来定义您感兴趣的关系。
这是一个简单的例子:
#include <algorithm>
#include <iostream>
#include <list>
struct matcher
{
matcher(int value) : target(value) {}
bool operator()(int lo, int hi) const {
return (lo < target) && (target < hi);
}
int target;
};
int main()
{
std::list<int> ticks = { 0, 100, 200, 300 };
auto it = std::adjacent_find(ticks.begin(), ticks.end(), matcher(214));
if (it != ticks.end()) {
std::cout << *it << ' ' << *std::next(it) << '\n';
} else {
std::cout << "not found\n";
}
}
这会输出200 300
,两个&#34;周围&#34;它找到的价值。