C++11 容器(1) forward_list

一 简介

1. C++11开始,STL增加了 forward_list 容器。它的实现是 singly linked list(单链表), 支持 foward iterator (前向迭代器)。

2. 单聊表进行元素的插入和删除是比较快速的,改动指针的指向即可,但前提是知道待处理节点的前驱节点。

3. 由于性能原因,forward_List 并没有提供 size 函数,也不能直接处理最末元素。size 可通过如下进行计算:

forward_list c;
auto size = std::distance(c.begin(), c.end());

4. forward_list 插入和移除元素,不会导致指向其他元素的pointer、reference 和 iterator 失效。

5. forward_list 由于自身特性,提供了一些特殊的迭代器和元素操作成员函数,下面分别展开。

二 迭代器

before_begincbefore_begin

返回指向第一个元素之前迭代器。

前面说过,例如插入需要知道前驱节点,那如果在开头插入,所以需要知道开头(begin)的前驱,也就是before_begin。

三 操作函数

其特殊的元素操作函数,是一批 xxx_after 函数。它们的处理范围也比较特殊。

1. insert_after

在容器中的指定位置后插入元素。

iterator insert_after( const_iterator pos, const T& value ); (1) (C++11 起)
iterator insert_after( const_iterator pos, T&& value ); (2) (C++11 起)
iterator insert_after( const_iterator pos, size_type count, const T& value ); (3) (C++11 起)
template< class InputIt >
iterator insert_after( const_iterator pos, InputIt first, InputIt last ); (4) (C++11 起)
iterator insert_after( const_iterator pos, std::initializer_list<T> ilist ); (5) (C++11 起)

例子1: 

// 为不影响阅读逻辑,打印数据均进行注释,下同
std::forward_list<int> c1 {1,2,3,4,5,6,7};
// print("original c1:", c1);

c1.insert_after(c1.before_begin(), 10);
// print("1 insert_after c1:", c1);
c1.insert_after(c1.begin(), 3, 30);
// print("2 insert_after c1:", c1);

std::forward_list<int> temp_c {100,200,300};
c1.insert_after(c1.before_begin(), temp_c.begin(), temp_c.end());
// print("3 insert_after c1:", c1);

结果:

original c1:
1 2 3 4 5 6 7

1 insert_after c1:
10 1 2 3 4 5 6 7

2 insert_after c1:
10 30 30 30 1 2 3 4 5 6 7

3 insert_after c1:
100 200 300 10 30 30 30 1 2 3 4 5 6 7

注意:

(1)pos 必须是有效迭代器(指向有效元素) 或 before_begin。在 pos 的下一位置插入。

(2) insert_after(4) 处理的区间为 [begin, end)

2. emplace_after

在容器中的指定位置后插入新元素。原位构造元素,即不进行复制或移动操作。

template< class... Args > 
iterator emplace_after( const_iterator pos, Args&&... args ); (C++11 起)

 例子2:

class A 
{
 public:
  explicit A(int a = 0) {}
  explicit A(int a, int b) {}
};

……
std::forward_list<A> temp_c;
A a1;
temp_c.insert_after(temp_c.before_begin(), a1);
temp_c.emplace_after(temp_c.before_begin(), 1);
temp_c.emplace_front(2,2);

// std::cout << "temp_c size:" << std::distance(temp_c.begin(), temp_c.end()) << std::endl;

结果:

temp_c size:3

3. erase_after

从容器移除指定元素。

iterator erase_after( const_iterator pos ); (1) (C++11 起)
iterator erase_after( const_iterator first, const_iterator last ); (2) (C++11 起)

例子3: 

// 代码接例子1
// print("c1", c1);
auto it = std::next(c1.begin(), 9);
c1.erase_after(c1.begin(), it);
// print("1 erase_after c1:", c1);
c1.erase_after(it);
// print("2 erase_after c1:", c1);

结果:

c1:
100 200 300 10 30 30 30 1 2 3 4 5 6 7

1 erase_after c1:
100 3 4 5 6 7

2 erase_after c1:
100 3 5 6 7

注意:

(1)erase_after(1) 移除的是 pos 的下一位置元素。(it 指向元素3, 第一次 erase_after 后仍有效;第二次 erase_after 移除的是其后的元素4)

(2)erase_after(2) 处理的区间为 (begin, end) 开区间。

4. splice_after

从另一 forward_list 移动元素到 *this 。不复制元素。

void splice_after( const_iterator pos, forward_list& other ); (1) (C++11 起)
void splice_after( const_iterator pos, forward_list&& other ); (1) (C++11 起)
void splice_after( const_iterator pos, forward_list& other, 
                   const_iterator it ); (2) (C++11 起)
void splice_after( const_iterator pos, forward_list&& other,
                   const_iterator it ); (2)	(C++11 起)
void splice_after( const_iterator pos, forward_list& other, 
                   const_iterator first, const_iterator last ); (3)	(C++11 起)
void splice_after( const_iterator pos, forward_list&& other, 
                   const_iterator first, const_iterator last ); (3)	(C++11 起)

例子4:

// 代码接例子3
// print("c1:", c1);
std::forward_list<int> temp_c {1000,2000,3000};
// print("original temp_c:", temp_c);
c1.splice_after(c1.before_begin(), temp_c);
// print("splice_after temp_c:", temp_c);
// print("splice_after c1:", c1);

std::forward_list<int> temp1_c {7000,8000,9000};
// print("original temp1_c:", temp1_c);
c1.splice_after(c1.before_begin(), temp1_c, temp1_c.begin());
// print("splice_after temp1_c:", temp1_c);
// print("splice_after c1:", c1);

c1.splice_after(c1.before_begin(), temp1_c, temp1_c.begin(), temp1_c.end());
// print("splice_after temp1_c:", temp1_c);
// print("splice_after c1:", c1);

结果:

c1:
100 3 5 6 7

original temp_c:
1000 2000 3000

splice_after temp_c:

splice_after c1:
1000 2000 3000 100 3 5 6 7

// -----------------------------

original temp1_c:
7000 8000 9000

splice_after temp1_c:
7000 9000

splice_after c1:
8000 1000 2000 3000 100 3 5 6 7

// -----------------------------

splice_after temp1_c:
7000

splice_after c1:
9000 8000 1000 2000 3000 100 3 5 6 7

注意:

(1)pos 必须是有效迭代器(指向有效元素) 或 before_begin。

(2)splice_after 是 move操作。(第一次操作后,temp_c 空了。)

(3)splice_after(2) move 的是 it 指向元素的下一元素。(第二次操作,move 的是 8000 而不是 7000。)

(4)splice_after(3) 处理的区间为 (begin, end) 开区间。(第三次操作,move 的是 9000 而不是 7000、9000。)

四 参考

forward_list

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值