C++ 遍历标准::列表,保存最后2个值

C++ 遍历标准::列表,保存最后2个值,c++,list,C++,List,我需要遍历包含2个最后值的std::list,即如果我的列表是[1,2,3,4,5,6] iteration1 : v1 = 1, v2 = 2 iteration2 : v1 = 2, v2 = 3 iteration3 : v1 = 3, v2 = 4 iteration4 : v1 = 4, v2 = 5 iteration5 : v1 = 5, v2 = 6 我试着 auto next = _contour.begin(); auto prev = next; while( next

我需要遍历包含2个最后值的
std::list
,即如果我的列表是
[1,2,3,4,5,6]

iteration1 : v1 = 1, v2 = 2
iteration2 : v1 = 2, v2 = 3
iteration3 : v1 = 3, v2 = 4
iteration4 : v1 = 4, v2 = 5
iteration5 : v1 = 5, v2 = 6
我试着

auto next = _contour.begin();
auto prev = next;

while( next != _contour.end())
{
    prev = next;
    next++;
}
但这并不好用——在遍历的末尾有一个问题。在上一次迭代中,
next
指向列表之外


如何在每次迭代检查时都能正确地执行我不希望的良好性能检查?

您的循环应该交换增量和检查条件,以避免超出范围。它可以通过多种方式完成,使用各种循环,例如

   auto  next = _contour.begin();
   auto prev = next;

   if( !_contour.empty())
     while( ++next != _contour.end())
     {
        //std::cout << *prev << ":" << *next << std::endl;
        prev = next;
     }

您的循环应该交换增量和检查条件,以避免超出边界。它可以通过多种方式完成,使用各种循环,例如

   auto  next = _contour.begin();
   auto prev = next;

   if( !_contour.empty())
     while( ++next != _contour.end())
     {
        //std::cout << *prev << ":" << *next << std::endl;
        prev = next;
     }

正如您所暗示的,问题是您要检查
next!=_contour.end()
在递增之前和递增之后,您无法确定它是否不等于end迭代器

要解决此问题,请切换循环中的逻辑,以便在每次迭代之前测试
next
的新值

例如:

auto current = _contour.begin();
// Make sure the list isn't empty before we go charging ahead.
if (current != _contour.end()) {
    decltype(current) prev;

    while ((prev = current), (++current != _contour.end())) {
        std::cout << "v1:" << *prev << " v2:" << *current << std::endl;
    }
}
auto current=_contour.begin();
//在我们继续充电之前,确保列表不是空的。
如果(当前!=\u轮廓.end()){
decltype(当前)prev;
而((prev=current),(++current!=\u contour.end()){

std::cout正如您所暗示的,问题在于在递增之前检查是否为
next!=\u contour.end()

要解决此问题,请切换循环中的逻辑,以便在每次迭代之前测试
next
的新值

例如:

auto current = _contour.begin();
// Make sure the list isn't empty before we go charging ahead.
if (current != _contour.end()) {
    decltype(current) prev;

    while ((prev = current), (++current != _contour.end())) {
        std::cout << "v1:" << *prev << " v2:" << *current << std::endl;
    }
}
auto current=_contour.begin();
//在我们继续充电之前,确保列表不是空的。
如果(当前!=\u轮廓.end()){
decltype(当前)prev;
而((prev=current),(++current!=\u contour.end()){

std::我认为代码是正确的。您确实检查了
next!=\u contour.end()
,所以它不应该超过该值。我猜真正的工作是在
next++
行之后完成的,并且
next
可以等于
.end()
。问题中的代码肯定是不正确的。无论OP将实际循环体放在哪里,它都不会做正确的事情。您不能在每次迭代时检查,因为列表可能在每次迭代时结束。您可以展开循环以增加一点性能,但您拥有的代码是标准的。@Evg我认为代码是正确的正确。您确实检查了
next!=\u contour.end()
,因此它不应该超过该值。我猜真正的作业是在
next++
行之后完成的,并且那里的
next
可以等于
.end()
。问题中的代码肯定是不正确的。无论OP将实际循环体放在哪里,它都不会做正确的事情。您不能在每次迭代时检查,因为列表可能在每次迭代时结束。您可以展开循环以增加一点性能,但您拥有的代码是标准的。@Evg注意事项:调用undefi如何如果列表为空,则调用未定义的行为。注意:如果列表为空,则调用未定义的行为。可能会将“current”移到
if()中
声明too@Swift-星期五不是没有多余的测试,除非我误解了你的意思。据我所知,你不能在同一个条件表达式中声明一个变量并测试它的初始值。在C++17中,
if(int I=1;I!=0){…}
^除非人们不总是能读懂逗号和分号的“魔力”@Evg啊,我不知道这个新语法。我只想说我的答案是C++11或更高版本。(我不喜欢假设每个人都可以访问C++17实现。)可能可以将“当前”改为
if()
声明too@Swift-星期五不是没有多余的测试,除非我误解了你的意思。据我所知,你不能在同一个条件表达式中声明一个变量并测试它的初始值。在C++17中,
if(int I=1;I!=0){…}
^除非人们不总是能读懂逗号和分号的“魔力”@Evg啊,我不知道这个新语法。我只想说我的答案是C++11或更高版本的。(我不喜欢假设每个人都可以访问C++17实现。)