forward_list 容器以单链表的形式存储元素。forward_list 的模板定义在头文件 forward_list 中。
fdrward_list 和 list 最主要的区别是:
- 它不能反向遍历元素;
- 只能从头到尾遍历。
forward_list 的单向链接性也意味着它会有一些其他的特性:
- 无法使用反向迭代器。只能从它得到const或non-const前向迭代器,这些迭代器都不能解引用,只能自增;
- 没有可以返回最后一个元素引用的成员函数back(),只有成员函数front();
- 因为只能通过自增前面元素的迭代器来到达序列的终点,所以push_back()、pop_back()、emplace_back()也无法使用。
forward_list 的操作比 list 容器还要快,而且占用的内存更少,尽管它在使用上有很多限制。
forward_list 容器的构造函数的使用方式和 list 容器相同。forward_list 的迭代器都是前向迭代器,它没有成员函数 size(),因此不能用一个前向迭代器减去另一个前向迭代器,但是可以通过使用定义在头文件 iterator 中的 distance() 函数来得到元素的个数。例如:
std::forward_list<std::string> my_words{"three", "six", "eight"};
auto count = std::distance(std::begin(my_words),std::end(my_words)); // Result is 3
distance() 的第一个参数是一个开始迭代器,第二个参数是一个结束迭代器,它们指定了元素范围。
当需要将前向迭代器移动多个位置时,advance() 就派上了用场。例如:
std::forward_list<int> data{10, 21, 43, 87, 175, 351};
auto iter = std::begin(data);
size_t n{3};
std::advance(iter, n);
std::cout << "The " << n+1 << "th element is " << *iter << std::endl; // Outputs 87
因为 forward_list 正向链接元素,所以只能在元素的后面插入或粘接另一个容器的元素,这一点和 list 容器的操作不同,list 可以在元素前进行操作。
forward_list 的成员函数 cbefore_begin() 和 before_begin() ,它们分别可以返回指向第一个元素之前位置的 const 和 non-const 迭代器,所以可以使用它们在开始位置插入或粘接元素,例如:
std::forward_list<std::string> my_words {"three", "six", "eight"}
std::forward_list<std::string> your_words {"seven", "four", "nine"};
my_words.splice_after(my_words.before_begin(), your_words, ++std::begin(your_words));
注意:这里的 std::begin(your_words) 指向 four ,而非 seven 。
经过这个操作后,my_words 会包含这些字符串对象:“nine”、“three”、“six”、“eight”,your_words 就只剩下两个字符串元素:"seven"和"four”。
另一个版本的 splice_after() 会将一个 forward_list 容器的全部元素粘接到另一个容器中:
my_words.splice_after(my_words.before_begin(), your_words);
上面的代码会将 your_words 中的全部元素拼接到第一个元素指定的位置。
forward_list 和 list —样都有成员函数 sort() 和 merge(),它们也都有 remove()、remove_if() 和unique(),所有这些函数的用法都和 list 相同。