- forward_list是一个由元素组成的单向链表,提供了O(1)复杂度的元素插入,不支持快速随机访问(这也是链表的特点),也是标准库容器中唯一一个不提供size()方法的容器。当不需要双向迭代时,具有比std::list更改的空间利用率
头文件:
#include <forward_list>
概述
创建、复制、销毁
非更易型操作
赋值
元素访问
迭代器相关函数
插入&&删除操作
构造函数
std::forward_list::forward_list
#include <forward_list>
#include <string>
#include <iostream>
template<typename T>
std::ostream& operator<<(std::ostream& s, const std::forward_list<T>& v)
{
s.put('[');
char comma[3] = {'\0', ' ', '\0'};
for (const auto& e : v) {
s << comma << e;
comma[0] = ',';
}
return s << ']';
}
int main()
{
std::forward_list<std::string> first; // default: empty
// std::forward_list<std::string> second ("aaa", "vvv"); // error
std::forward_list<std::string> words1 {"the", "frogurt", "is", "also", "cursed"};
std::forward_list<std::string> words2(words1.begin(), words1.end());
std::forward_list<std::string> words3(words1);
std::forward_list<std::string> words4(5, "Mo");
std::forward_list<std::string> words5 = {"the", "frogurt", "is", "also", "cursed"};
std::cout << "first: " << first << '\n';
// std::cout << "second: " << second << '\n';
std::cout << "words1: " << words1 << '\n';
std::cout << "words2: " << words2 << '\n';
std::cout << "words3: " << words3 << '\n';
std::cout << "words4: " << words4 << '\n';
std::cout << "words5: " << words5 << '\n';
std::forward_list<std::string> words6(std::move(words5));
std::cout << "words5: " << words5 << '\n';
std::cout << "words6: " << words6 << '\n';
}
std::forward_list::operator=
作用:替换容器内容
#include <forward_list>
#include <iostream>
void display_sizes(const std::forward_list<int> &nums1,
const std::forward_list<int> &nums2,
const std::forward_list<int> &nums3)
{
std::cout << "nums1: " << std::distance(nums1.begin(), nums1.end())
<< " nums2: " << std::distance(nums2.begin(), nums2.end())
<< " nums3: " << std::distance(nums3.begin(), nums3.end()) << '\n';
}
int main()
{
std::forward_list<int> nums1 {3, 1, 4, 6, 5, 9};
std::forward_list<int> nums2;
std::forward_list<int> nums3;
std::cout << "Initially:\n";
display_sizes(nums1, nums2, nums3);
// 复制赋值从 nums1 复制数据到 nums2
nums2 = nums1;
std::cout << "After assigment:\n";
display_sizes(nums1, nums2, nums3);
// 移动赋值从 nums1 移动数据到 nums3,
// 修改 nums1 和 nums3
nums3 = std::move(nums1);
std::cout << "After move assigment:\n";
display_sizes(nums1, nums2, nums3);
}
元素访问
#include <forward_list>
#include <iostream>
int main()
{
std::forward_list<char> letters {'o', 'm', 'g', 'w', 't', 'f'};
if (!letters.empty()) {
std::cout << "The first character is: " << letters.front() << '\n';
}
}
迭代器
std :: forward_list :: before_begin
作用:返回一个迭代器,该迭代器指向容器中第一个元素之前的位置。
std :: forward_list :: cbefore_begin
作用:
- 返回一个const_iterator,指向容器中第一个元素之前的位置。
- 一个常量性是一个迭代器,它指向常量内容。可以增加和减少此迭代器(除非它本身也为const),就像forward_list :: before_begin返回的迭代器一样,但不能用于修改其指向的内容。
// forward_list::before_begin
#include <iostream>
#include <forward_list>
int main ()
{
std::forward_list<int> mylist = {20, 30, 40, 50};
mylist.insert_after ( mylist.before_begin(), 11 );
// mylist.insert_after ( mylist.cbefore_begin(), 11 );
std::cout << "mylist contains:";
for ( int& x: mylist ) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
std::forward_list::begin、std :: forward_list :: cbegin、std::forward_list::end
- begin:返回指向forward_list容器中第一个元素的迭代器。
-
cbegin:返回指向容器中第一个元素的const_iterator。
- end:返回指向forward_list容器中最后一个元素的后面的位置。
// forward_list::begin example
#include <iostream>
#include <forward_list>
int main ()
{
std::forward_list<int> mylist = { 34, 77, 16, 2 };
std::cout << "mylist contains:";
for ( auto it = mylist.begin(); it != mylist.end(); ++it )
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
// forward_list::cbegin/cend example
#include <iostream>
#include <forward_list>
int main ()
{
std::forward_list<int> mylist = { 21, 32, 12 };
std::cout << "myarray contains:";
for ( auto it = mylist.cbegin(); it != mylist.cend(); ++it )
std::cout << ' ' << *it; // cannot modify *it
std::cout << '\n';
return 0;
}
容量
std::forward_list::empty
作用:返回一个bool值,该值指示forward_list容器是否为空,即其大小是否为0。
// forward_list::empty
#include <iostream>
#include <forward_list>
int main ()
{
std::forward_list<int> first;
std::forward_list<int> second = {20, 40, 80};
std::cout << "first " << (first.empty() ? "is empty" : "is not empty" ) << std::endl;
std::cout << "second " << (second.empty() ? "is empty" : "is not empty" ) << std::endl;
return 0;
}
std::forward_list::max_size
作用:
- 返回根据系统或库实现限制的容器可保有的元素最大数量
- 此值通常反映容器大小上的理论极限,至多为 std::numeric_limits<difference_type>::max() 。运行时,可用 RAM 总量可能会限制容器大小到小于
max_size()
的值
#include <iostream>
#include <forward_list>
int main()
{
std::forward_list<char> s;
std::cout << "Maximum size of a 'forward_list' is " << s.max_size() << "\n";
}
修改器
std::forward_list::assign
作用:替换容器内容
// forward_list::assign
#include <iostream>
#include <forward_list>
int main ()
{
std::forward_list<int> first;
std::forward_list<int> second;
first.assign (4,15); // 15 15 15 15
second.assign (first.begin(),first.end()); // 15 15 15 15
first.assign ( {77, 2, 16} ); // 77 2 16
std::cout << "first contains: ";
for (int& x : first) std::cout << ' ' << x;
std::cout << '\n';
std::cout << "second contains: ";
for (int& x : second) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
std :: forward_list :: emplace_front
作用:在开始时构造并插入元素
// forward_list::emplace_front
#include <iostream>
#include <forward_list>
int main ()
{
std::forward_list< std::pair<int,char> > mylist;
mylist.emplace_front(10,'a');
mylist.emplace_front(20,'b');
mylist.emplace_front(30,'c');
std::cout << "mylist contains:";
for (auto& x: mylist)
std::cout << " (" << x.first << "," << x.second << ")";
std::cout << std::endl;
return 0;
}
void push_front(const value_type&val);
void push_front(value_type && val);
std :: forward_list :: push_front
作用:
在forward_list的开始处插入一个新元素,紧接其当前第一个元素之前。val的内容被复制(或移动)到插入的元素。
// forward_list::push_front
#include <iostream>
#include <forward_list>
using namespace std;
int main ()
{
forward_list<int> mylist = {77, 2, 16};
mylist.push_front (19);
mylist.push_front (34);
std::cout << "mylist contains:";
for (int& x: mylist) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
删除第一个元素
std::forward_list::clear
#include <algorithm>
#include <iostream>
#include <forward_list>
int main()
{
std::forward_list<int> container{1, 2, 3};
auto print = [](const int& n) { std::cout << " " << n; };
std::cout << "Before clear:";
std::for_each(container.begin(), container.end(), print);
std::cout << '\n';
std::cout << "Clear\n";
container.clear();
std::cout << "After clear:";
std::for_each(container.begin(), container.end(), print);
std::cout << '\n';
}
std::forward_list::insert_after
作用:在容器中的指定位置后插入元素。
#include <forward_list>
#include <string>
#include <iostream>
#include <vector>
template<typename T>
std::ostream& operator<<(std::ostream& s, const std::forward_list<T>& v) {
s.put('[');
char comma[3] = {'\0', ' ', '\0'};
for (const auto& e : v) {
s << comma << e;
comma[0] = ',';
}
return s << ']';
}
int main()
{
std::forward_list<std::string> words {"the", "frogurt", "is", "also", "cursed"};
std::cout << "words: " << words << '\n';
// insert_after (2)
auto beginIt = words.begin();
words.insert_after(beginIt, "strawberry");
std::cout << "words: " << words << '\n';
// insert_after (3)
auto anotherIt = beginIt;
++anotherIt;
anotherIt = words.insert_after(anotherIt, 2, "strawberry");
std::cout << "words: " << words << '\n';
// insert_after (4)
std::vector<std::string> V = { "apple", "banana", "cherry"};
anotherIt = words.insert_after(anotherIt, V.begin(), V.end());
std::cout << "words: " << words << '\n';
// insert_after (5)
words.insert_after(anotherIt, {"jackfruit", "kiwifruit", "lime", "mango"});
std::cout << "words: " << words << '\n';
}
std::forward_list::emplace_after
#include <forward_list>
#include <iostream>
#include <string>
struct Sum {
std::string remark;
int sum;
Sum(std::string remark, int sum)
: remark{std::move(remark)}, sum{sum} {}
void print() const {
std::cout << remark << " = " << sum << '\n';
}
};
int main()
{
std::forward_list<Sum> list;
auto iter = list.before_begin();
std::string str{"1"};
for (int i{1}, sum{1}; i != 10; sum += i) {
iter = list.emplace_after(iter, str, sum);
++i;
str += " + " + std::to_string(i);
}
for (const Sum& s : list) s.print();
}
std::forward_list::erase_after
#include <forward_list>
#include <iterator>
#include <iostream>
int main()
{
std::forward_list<int> l = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// l.erase( l.begin() ); // 错误:无要擦除的元素
l.erase_after( l.before_begin() ); // 移除首元素
for( auto n : l ) std::cout << n << " ";
std::cout << '\n';
auto fi= std::next( l.begin() );
auto la= std::next( fi, 3 );
l.erase_after( fi, la );
for( auto n : l ) std::cout << n << " ";
std::cout << '\n';
}
std::forward_list::resize
#include <iostream>
#include <forward_list>
int main()
{
std::forward_list<int> c = {1, 2, 3};
std::cout << "The forward_list holds: ";
for(auto& el: c) std::cout << el << ' ';
std::cout << '\n';
c.resize(5);
std::cout << "After resize up to 5: ";
for(auto& el: c) std::cout << el << ' ';
std::cout << '\n';
c.resize(2);
std::cout << "After resize down to 2: ";
for(auto& el: c) std::cout << el << ' ';
std::cout << '\n';
}
操作
std::forward_list::merge
#include <iostream>
#include <forward_list>
std::ostream& operator<<(std::ostream& ostr, const std::forward_list<int>& list)
{
for (auto &i : list) {
ostr << " " << i;
}
return ostr;
}
int main()
{
std::forward_list<int> list1 = { 5,9,0,1,3 };
std::forward_list<int> list2 = { 8,7,2,6,4 };
list1.sort();
list2.sort();
std::cout << "list1: " << list1 << "\n";
std::cout << "list2: " << list2 << "\n";
list1.merge(list2);
std::cout << "merged: " << list1 << "\n";
}
从另一个forward_list转移元素
std::forward_list::splice_after
#include <iostream>
#include <forward_list>
int main()
{
std::forward_list<int> l1 = {1, 2, 3, 4, 5};
std::forward_list<int> l2 = {10, 11, 12};
l2.splice_after(l2.cbegin(), l1, l1.cbegin(), l1.cend());
// 不等价于 l2.splice_after(l2.cbegin(), l1);
for (int n : l1)
std::cout << n << ' ';
std::cout << '\n';
for (int n : l2)
std::cout << n << ' ';
std::cout << '\n';
}
std::forward_list::remove, remove_if
#include <forward_list>
#include <iostream>
int main()
{
std::forward_list<int> l = { 1,100,2,3,10,1,11,-1,12 };
l.remove(1); // 移除两个等于 1 的元素
l.remove_if([](int n){ return n > 10; }); // 移除全部大于 10 的元素
for (int n : l) {
std::cout << n << ' ';
}
std::cout << '\n';
}
std::forward_list::reverse
#include <iostream>
#include <forward_list>
std::ostream& operator<<(std::ostream& ostr, const std::forward_list<int>& list)
{
for (auto &i : list) {
ostr << " " << i;
}
return ostr;
}
int main()
{
std::forward_list<int> list = { 8,7,5,9,0,1,3,2,6,4 };
std::cout << "before: " << list << "\n";
list.sort();
std::cout << "ascending: " << list << "\n";
list.reverse();
std::cout << "descending: " << list << "\n";
}
std::forward_list::unique
#include <iostream>
#include <forward_list>
int main()
{
std::forward_list<int> x = {1, 2, 2, 3, 3, 2, 1, 1, 2};
std::cout << "contents before:";
for (auto val : x)
std::cout << ' ' << val;
std::cout << '\n';
x.unique();
std::cout << "contents after unique():";
for (auto val : x)
std::cout << ' ' << val;
std::cout << '\n';
return 0;
}
std::forward_list::sort
#include <iostream>
#include <functional>
#include <forward_list>
std::ostream& operator<<(std::ostream& ostr, const std::forward_list<int>& list)
{
for (auto &i : list) {
ostr << " " << i;
}
return ostr;
}
int main()
{
std::forward_list<int> list = { 8,7,5,9,0,1,3,2,6,4 };
std::cout << "before: " << list << "\n";
list.sort();
std::cout << "ascending: " << list << "\n";
list.sort(std::greater<int>());
std::cout << "descending: " << list << "\n";
}
std::swap(std::forward_list)
#include <algorithm>
#include <iostream>
#include <forward_list>
int main()
{
std::forward_list<int> alice{1, 2, 3};
std::forward_list<int> bob{7, 8, 9, 10};
auto print = [](const int& n) { std::cout << " " << n; };
// 打印交换前的状态
std::cout << "alice:";
std::for_each(alice.begin(), alice.end(), print);
std::cout << '\n';
std::cout << "bob :";
std::for_each(bob.begin(), bob.end(), print);
std::cout << '\n';
std::cout << "-- SWAP\n";
std::swap(alice,bob);
// 打印交换后的状态
std::cout << "alice:";
std::for_each(alice.begin(), alice.end(), print);
std::cout << '\n';
std::cout << "bob :";
std::for_each(bob.begin(), bob.end(), print);
std::cout << '\n';
}
std::erase, std::erase_if (std::forward_list)
#include <iostream>
#include <numeric>
#include <forward_list>
void print_container(const std::forward_list<char>& c)
{
for (auto x : c) {
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::forward_list<char> cnt(10);
std::iota(cnt.begin(), cnt.end(), '0');
std::cout << "Init:\n";
print_container(cnt);
auto erased = std::erase(cnt, '3');
std::cout << "Erase \'3\':\n";
print_container(cnt);
std::erase_if(cnt, [](char x) { return (x - '0') % 2 == 0; });
std::cout << "Erase all even numbers:\n";
print_container(cnt);
std::cout << "In all " << erased << " even numbers were erased.\n";
}