容器库(5)-std::list

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 
相关推荐
charlie11451419113 小时前
通用GUI编程技术——图形渲染实战(四十)——深度缓冲与3D变换:从平面到立体
开发语言·c++·平面·3d·图形渲染·win32
啊吧怪不啊吧13 小时前
C++之基于正倒排索引的Boost搜索引擎项目日志+server代码及详解
c++·搜索引擎·项目
小张同学82413 小时前
-RAG检索增强生成让智能体拥有企业级专属知识库
开发语言·python·架构·pycharm
DevilSeagull13 小时前
Rust 枚举(enum)深度解析:从定义到 Option 的安全之道
开发语言·后端·安全·rust·github
Ulyanov13 小时前
《现代 Python 桌面应用架构实战:PySide6 + QML 从入门到工程化》:实时时钟与数据驱动 UI —— 从“事件回调”到“状态绑定”的范式跃迁
开发语言·python·qt·ui·架构·交互
AI进化营-智能译站13 小时前
ROS2 C++开发系列06:变量、数据类型与IO实战
java·开发语言·c++·ai
HABuo15 小时前
【linux(四)】套接字编程--基于UDP协议的客户端服务端
linux·服务器·c++·网络协议·ubuntu·udp·centos
阿里嘎多学长20 小时前
2026-04-30 GitHub 热点项目精选
开发语言·程序员·github·代码托管
j_xxx404_1 天前
Linux:静态链接与动态链接深度解析
linux·运维·服务器·c++·人工智能
叶小鸡1 天前
Java 篇-项目实战-苍穹外卖-笔记汇总
java·开发语言·笔记