std::forward_list是可以从任何位置快速插入和移除元素的容器,不支持快速随机访问,支持正向和反向的迭代。
本文章的代码库:
https://gitee.com/gamestorm577/CppStd
成员函数
构造、析构和赋值
构造函数
可以用元素、元素列表、迭代器或者另一个list来构造list。代码示例:
cpp
auto print_func = [](const std::list<float>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::vector<float> vec{1.1f, 2.1f, 3.1f};
std::list<float> l1(5, 1.1f);
std::list<float> l2(5);
std::list<float> l3(vec.begin(), vec.end());
std::list<float> l4(l1);
std::list<float> tmp(l1);
std::list<float> l5(std::move(tmp));
std::list<float> l6{11.1f, 12.1, 13.1f};
print_func(l1);
print_func(l2);
print_func(l3);
print_func(l4);
print_func(l5);
print_func(l6);
输出结果:
bash
1.1 1.1 1.1 1.1 1.1
0 0 0 0 0
1.1 2.1 3.1
1.1 1.1 1.1 1.1 1.1
1.1 1.1 1.1 1.1 1.1
11.1 12.1 13.1
析构函数
list析构时,会按照正向顺序依次删除元素。代码示例:
cpp
struct MyStruct
{
MyStruct(int i)
: Index(i)
{
}
~MyStruct()
{
std::cout << "destruct, Index = " << Index << std::endl;
}
int Index = 0;
};
std::list<MyStruct> l;
l.emplace_front(1);
l.emplace_front(3);
l.emplace_front(5);
输出结果:
bash
destruct, Index = 5
destruct, Index = 3
destruct, Index = 1
赋值函数
可以用元素列表或者另一个list赋值给forward_list。代码示例:
cpp
auto print_func = [](const std::list<float>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::list<float> tmp = {1.1f, 2.1f, 3.1f};
std::list<float> l1;
std::list<float> l2;
l1 = tmp;
l2 = {2.1f, 2.2f, 2.3f, 2.4f};
print_func(l1);
print_func(l2);
输出结果:
bash
1.1 2.1 3.1
2.1 2.2 2.3 2.4
assign
将值赋值给forward_list,可以是元素、元素列表或者迭代器。代码示例:
cpp
auto print_func = [](const std::list<float>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::vector<float> vec(10, 1.2f);
std::list<float> l;
l.assign(5, 1.2);
print_func(l);
l.assign(vec.begin(), vec.end());
print_func(l);
l.assign({1.1f, 2.1f, 3.1f});
print_func(l);
输出结果:
bash
1.2 1.2 1.2 1.2 1.2
1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2
1.1 2.1 3.1
元素访问
front
返回首个元素的引用。示例代码:
cpp
std::list<float> l = {1.f, 2.f, 3.f};
l.front() = 4.1f;
std::cout << "l front is: " << l.front() << std::endl;
输出结果:
bash
l front is: 4.1
back
返回最后一个元素的引用。示例代码:
cpp
std::list<float> l = {1.f, 2.f, 3.f};
l.back() = 24.1f;
std::cout << "l back is: " << l.back() << std::endl;
输出结果:
bash
l back is: 24.1
迭代器
接口begin、cbegin指向list起始的迭代器,end、cend指向末尾的迭代器。rbegin、crbegin指向起始的逆向迭代器,rend、crend指向末尾的逆向迭代器。代码示例:
cpp
std::list<float> l = {1.1f, 2.1f, 3.1f};
for (auto iter = l.rbegin(); iter != l.rend(); ++iter)
{
*iter += 27.f;
}
for (auto iter = l.crbegin(); iter != l.crend(); ++iter)
{
std::cout << "num is: " << *iter << std::endl;
}
输出结果:
bash
num is: 30.1
num is: 29.1
num is: 28.1
容量
empty
检查list是否为空。示例代码:
cpp
std::list<float> l1 = {1.1f, 2.1f, 3.1f};
std::list<float> l2;
std::cout << std::boolalpha;
std::cout << "l1 empty: " << l1.empty() << std::endl;
std::cout << "l2 empty: " << l2.empty() << std::endl;
输出结果:
bash
l1 empty: false
l2 empty: true
size
获取list元素的个数。代码示例:
cpp
std::list<float> l1 = {1.1f, 2.1f, 3.1f};
std::list<float> l2;
std::cout << "l1 size = " << l1.size() << std::endl;
std::cout << "l2 size = " << l2.size() << std::endl;
输出结果:
bash
l1 size = 3
l2 size = 0
max_size
返回可以容纳的最大元素个数。代码示例:
cpp
struct MyStruct
{
double num1;
double num2;
double num3;
double num4;
};
std::list<float> l1;
std::list<double> l2;
std::list<MyStruct> l3;
std::cout << "l1 max size = " << l1.max_size() << std::endl;
std::cout << "l2 max size = " << l2.max_size() << std::endl;
std::cout << "l3 max size = " << l3.max_size() << std::endl;
输出结果:
bash
l1 max size = 768614336404564650
l2 max size = 768614336404564650
l3 max size = 384307168202282325
修改器
clear
清除所有的元素。代码示例:
cpp
std::list<float> l(3, 1.f);
std::cout << std::boolalpha;
std::cout << "l empty: " << l.empty() << std::endl;
l.clear();
std::cout << "l empty: " << l.empty() << std::endl;
输出结果:
bash
l empty: false
l empty: true
insert
在指定的位置插入元素。代码示例:
cpp
auto print_func = [](const std::list<float>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::vector<float> vec{40.1f, 40.2f};
std::list<float> l = {1.1f, 1.2f, 1.3f};
print_func(l);
l.insert(l.begin(), 15.7f);
print_func(l);
l.insert(std::next(l.begin(), 2), 3, 27.9f);
print_func(l);
l.insert(std::next(l.begin(), 1), vec.begin(), vec.end());
print_func(l);
l.insert(std::next(l.begin(), 1), {70.5f, 75.5f, 71.5f});
print_func(l);
输出结果:
bash
1.1 1.2 1.3
15.7 1.1 1.2 1.3
15.7 1.1 27.9 27.9 27.9 1.2 1.3
15.7 40.1 40.2 1.1 27.9 27.9 27.9 1.2 1.3
15.7 70.5 75.5 71.5 40.1 40.2 1.1 27.9 27.9 27.9 1.2 1.3
emplace
在指定位置一个元素。代码示例:
cpp
struct MyStruct
{
MyStruct(float num1, int num2)
{
std::cout << "construct " << num1 << " " << num2 << std::endl;
}
};
std::list<MyStruct> f;
f.emplace(f.begin(), 5.5f, 20);
输出结果:
cpp
construct 5.5 20
erase
删除指定位置的元素。代码示例:
cpp
auto print_func = [](const std::list<float>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::list<float> l = {1.1f, 1.2f, 1.3f, 1.5f, 1.6f, 1.7f, 1.8f};
print_func(l);
l.erase(std::next(l.begin(), 1));
print_func(l);
l.erase(std::next(l.begin(), 1), std::next(l.begin(), 5));
print_func(l);
输出结果:
bash
1.1 1.2 1.3 1.5 1.6 1.7 1.8
1.1 1.3 1.5 1.6 1.7 1.8
1.1 1.8
push_back
将元素添加到末尾。代码示例:
cpp
auto print_func = [](const std::list<float>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::list<float> l = {1.1f, 1.2f};
l.push_back(1.3f);
l.push_back(1.4f);
print_func(l);
输出结果:
bash
1.1 1.2 1.3 1.4
emplace_back
在列表末尾构造一个元素。代码示例:
cpp
struct MyStruct
{
MyStruct(float num1, int num2)
{
std::cout << "construct " << num1 << " " << num2 << std::endl;
}
};
std::list<MyStruct> l;
l.emplace_back(1.5f, 17);
l.emplace_back(2.3f, 4);
输出结果:
bash
construct 1.5 17
construct 2.3 4
pop_back
移除末尾的元素。代码示例:
cpp
std::list<float> l = {1.1f, 1.2f, 1.3f};
std::cout << "l back is: " << l.back() << std::endl;
l.pop_back();
std::cout << "l back is: " << l.back() << std::endl;
输出结果:
bash
l back is: 1.3
l back is: 1.2
push_front
将元素添加到起始位置。代码示例:
cpp
std::list<float> l = {1.1f, 1.2f, 1.3f};
std::cout << "l front is: " << l.front() << std::endl;
l.push_front(17.7f);
std::cout << "l front is: " << l.front() << std::endl;
输出结果:
bash
l front is: 1.1
l front is: 17.7
emplace_front
在列表起始位置构造一个元素。代码示例:
cpp
struct MyStruct
{
MyStruct(float num1, int num2)
{
std::cout << "construct " << num1 << " " << num2 << std::endl;
}
};
std::list<MyStruct> l;
l.emplace_front(2.7f, 17);
l.emplace_front(15.1f, 13);
输出结果:
bash
construct 2.7 17
construct 15.1 13
pop_front
移除列表的首个元素。代码示例:
cpp
std::list<float> l = {1.1f, 1.2f, 1.3f};
std::cout << "l front is: " << l.front() << std::endl;
l.pop_front();
std::cout << "l front is: " << l.front() << std::endl;
输出结果:
bash
l front is: 1.1
l front is: 1.2
resize
重新设置元素的个数。代码示例:
cpp
std::list<float> l = {1.1f, 1.2f, 1.3f};
std::cout << "l size is: " << l.size() << std::endl;
l.resize(2);
std::cout << "l size is: " << l.size() << std::endl;
l.resize(20);
std::cout << "l size is: " << l.size() << std::endl;
输出结果:
bash
l size is: 3
l size is: 2
l size is: 20
swap
交换两个列表的元素内容。代码示例:
cpp
std::list<float> l1 = {1.1f, 1.2f, 1.3f};
std::list<float> l2 = {2.1f, 2.2f};
l1.swap(l2);
std::cout << "l1 size = " << l1.size() << std::endl;
std::cout << "l2 size = " << l2.size() << std::endl;
输出结果:
bash
l1 size = 2
l2 size = 3
操作
sort
对元素进行排序。代码示例:
cpp
auto print_func = [](const std::list<int>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::list<int> l = {7, 17, 5, 47, 25};
print_func(l);
l.sort();
print_func(l);
l.sort(
[](int a, int b)
{
return a > b;
});
print_func(l);
输出结果:
bash
7 17 5 47 25
5 7 17 25 47
47 25 17 7 5
merge
合并两个有序的列表。代码示例:
cpp
auto print_func = [](const std::list<int>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
{
std::list<int> l1 = {1, 5, 7, 19};
std::list<int> l2 = {2, 3, 14, 15};
l1.merge(l2);
print_func(l1);
}
{
std::list<int> l1 = {1, 5, 7, 19};
std::list<int> l2 = {2, 3, 14, 15};
l1.merge(l2,
[](int a, int b)
{
return a > b;
});
print_func(l1);
}
输出结果:
bash
1 2 3 5 7 14 15 19
2 3 14 15 1 5 7 19
splice
将另一个列表中的一些元素移动到this列表指定的位置。代码示例:
cpp
auto print_func = [](std::string tag, const std::list<float>& list)
{
std::cout << tag;
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
{
std::list<float> l1 = {1.5f, 5.5f, 7.5f, 19.5f};
std::list<float> l2 = {2.4f, 3.4f, 14.4f, 15.4f};
l1.splice(l1.begin(), l2);
print_func("l1 = ", l1);
print_func("l2 = ", l2);
}
{
std::list<float> l1 = {1.5f, 5.5f, 7.5f, 19.5f};
std::list<float> l2 = {2.4f, 3.4f, 14.4f, 15.4f};
l1.splice(std::next(l1.begin(), 2), l2, std::next(l2.begin(), 1));
print_func("l1 = ", l1);
print_func("l2 = ", l2);
}
{
std::list<float> l1 = {1.5f, 5.5f, 7.5f, 19.5f};
std::list<float> l2 = {2.4f, 3.4f, 14.4f, 15.4f};
l1.splice(l1.begin(), l2, l2.begin(), std::next(l2.begin(), 2));
print_func("l1 = ", l1);
print_func("l2 = ", l2);
}
输出结果:
bash
l1 = 2.4 3.4 14.4 15.4 1.5 5.5 7.5 19.5
l2 =
l1 = 1.5 5.5 3.4 7.5 19.5
l2 = 2.4 14.4 15.4
l1 = 2.4 3.4 1.5 5.5 7.5 19.5
l2 = 14.4 15.4
remove、remove_if
remove移除等于指定值的元素。remove_if移除满足指定要求的元素。代码示例:
cpp
auto print_func = [](const std::list<int>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::list<int> l = {5, 9, 17, 27, 15, 5, 5};
print_func(l);
l.remove(5);
print_func(l);
l.remove_if(
[](int n)
{
return n > 15;
});
print_func(l);
输出结果:
bash
5 9 17 27 15 5 5
9 17 27 15
9 15
reverse
反转元素的顺序。代码示例:
cpp
auto print_func = [](const std::list<float>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::list<float> l = {1.1f, 3.1f, 19.1f, 7.1f};
print_func(l);
l.reverse();
print_func(l);
输出结果:
bash
1.1 3.1 19.1 7.1
7.1 19.1 3.1 1.1
unique
删除连续的重复元素。代码示例:
cpp
auto print_func = [](const std::list<int>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::list<int> l = {1, 3, 3, 17, 7, 3, 17, 17, 19, 1, 3, 1};
print_func(l);
l.unique();
print_func(l);
输出结果:
bash
1 3 3 17 7 3 17 17 19 1 3 1
1 3 17 7 3 17 19 1 3 1
非成员函数
比较运算符
operator==,!=,<,<=,>,>=用于比较两个forward_list。代码示例:
cpp
std::list<int> l1 = {1, 2, 3, 4};
std::list<int> l2 = {1, 5};
std::cout << std::boolalpha;
std::cout << "l1 == l2: " << (l1 == l2) << std::endl;
std::cout << "l1 != l2: " << (l1 != l2) << std::endl;
std::cout << "l1 < l2: " << (l1 < l2) << std::endl;
std::cout << "l1 <= l2: " << (l1 <= l2) << std::endl;
std::cout << "l1 > l2: " << (l1 > l2) << std::endl;
std::cout << "l1 >= l2: " << (l1 >= l2) << std::endl;
输出结果:
bash
l1 == l2: false
l1 != l2: true
l1 < l2: true
l1 <= l2: true
l1 > l2: false
l1 >= l2: false
swap
交换两个列表的元素内容。示例代码:
cpp
std::list<float> l1 = {1.5f, 2.5f};
std::list<float> l2 = {17.1f, 15.1f, 27.1f};
std::swap(l1, l2);
std::cout << "l1 front is: " << l1.front() << std::endl;
std::cout << "l2 front is: " << l2.front() << std::endl;
输出结果:
bash
l1 front is: 17.1
l2 front is: 1.5
erase、erase_if
erase删除等于指定值的元素,erase_if删除满足条件的元素。代码示例:
cpp
auto print_func = [](const std::list<int>& list)
{
for (auto i : list)
{
std::cout << i << " ";
}
std::cout << std::endl;
};
std::list<int> l = {5, 7, 17, 29, 7, 7, 35};
print_func(l);
std::erase(l, 7);
print_func(l);
std::erase_if(l,
[](int a)
{
return a > 17;
});
print_func(l);
输出结果:
bash
5 7 17 29 7 7 35
5 17 29 35
5 17