凝聚循环..(C ++)

时间:2017-10-30 20:04:12

标签: c++ insert iterator singly-linked-list

我偶然发现了这段代码并试图理解它,某些部分很清楚但不适合循环:

forward_list<Class> obj;
auto b_end = obj.before_begin();

for (auto& _ : obj)
    ++b_end ;

obj.insert_after(b_end, Class newObj);

不完全确定循环正在做什么。有些人可以打破for循环并帮助我理解吗?

编辑: 此问题标记为重复,但其他线程未提供足够的信息和/或太旧。

2 个答案:

答案 0 :(得分:1)

此:

forward_list<Class> obj;

声明Class obj - 名为std::。由于在代码中的某处使用了using namespace std;,因此省略了auto b_end = obj.before_begin(); 部分。 这样:

obj

定义一个指向for (auto& _ : obj) ++b_end; 列表中std::forward_list位置的迭代器。 这样:

_

std::forward_list::before_begin,它使用通过引用传递的奇怪命名的b_end变量。在此循环中,obj.insert_after(b_end, Class newObj); 在每次迭代中递增。 最后:

newObj

尝试在Class位置后插入b_end类型的新Class newObj; obj.insert_after(b_end, newObj); 并且无法编译,因为它应该是:

_

话虽如此,_只是一个变量名。它是一个(有点不寻常)有效的变量标识符。在这里,for (auto el : obj){ ++b_end; } 变量本身在for循环中没有以任何方式使用,所以整个事情可能被重写为:

auto

this.postServices.getPost(id).subscribe( (res) => { this.video = 'http://127.0.0.1:9111/api/get/video.mp4'; }) 关键字代表range based for loop

答案 1 :(得分:1)

std::forward_list是一个带有forward_iterators的顺序容器。这是一个片面的单链表。要在列表中插入值,只能使用方法insert_after指定范围[begin(), end())中的迭代器或方法before_begin()返回的迭代器。

来自C ++标准

  

5要求:position是before_begin()或者是dereferenceable   迭代器的范围是[begin(),end())。

因此,如果要将新值附加到列表的末尾,则必须将迭代器移动到与列表中最后一个元素对应的位置。

所以这个循环命名为基于范围的循环

for (auto& _ : obj)
    ++b_end ;

在列表中最后一个元素占用的位置逐步移动迭代器b_end。所以现在使用迭代器,您可以使用方法insert_after将新值附加到列表中。

考虑一个简单的示范程序。

#include <iostream>
#include <forward_list>

int main()
{
    std::forward_list<int> lst = { 1, 2 };

    auto b_end = lst.before_begin();

    for (const auto &_ : lst)
    {
        ++b_end;
        std::cout << *b_end << '\n';
    }
    std::cout << std::endl;

    lst.insert_after(b_end, 3);

    for (const auto &_ : lst) std::cout << _ << ' ';
    std::cout << std::endl;

    return 0;
}

程序输出

1
2

1 2 3

首先,迭代器b_end指向列表中第一个元素之前。

    auto b_end = lst.before_begin();
                     ^^^^^^^^^^^^^^

之后在循环中将有两次迭代,因为列表只包含两个元素,迭代器首先将移动到与第一个元素对应的位置,然后移动到与第二个元素对应的位置。

现在使用获得的迭代器,我们可以在值2之后添加值。