容器库(4)-std::forward_list

std::forward_list是可以从任何位置快速插入和移除元素的容器,不支持快速随机访问,只支持正向迭代。

本文章的代码库:

https://gitee.com/gamestorm577/CppStd

成员函数

构造、析构和赋值

构造函数

可以用元素、元素列表、迭代器或者另一个forward_list来构造forward_list。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<float> vec(10, 1.2f);

std::forward_list<float> f1(4, 3.2f);
std::forward_list<float> f2(4);
std::forward_list<float> f3(vec.begin(), vec.end());
std::forward_list<float> f4(f1);
std::forward_list<float> tmp(f1);
std::forward_list<float> f5(std::move(tmp));
std::forward_list<float> f6{1.f, 2.f, 3.f};

print_func(f1);
print_func(f2);
print_func(f3);
print_func(f4);
print_func(f5);
print_func(f6);

输出结果:

bash 复制代码
3.2 3.2 3.2 3.2 
0 0 0 0 
1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2 
3.2 3.2 3.2 3.2 
3.2 3.2 3.2 3.2 
1 2 3 

析构函数

forward_list析构时,会按照正向顺序依次删除元素。代码示例:

cpp 复制代码
struct MyStruct
{
    MyStruct(int i)
        : Index(i)
    {
    }

    ~MyStruct()
    {
        std::cout << "destruct, Index = " << Index << std::endl;
    }

    int Index = 0;
};

std::forward_list<MyStruct> f;
f.emplace_front(1);
f.emplace_front(3);
f.emplace_front(5);

输出结果:

bash 复制代码
destruct, Index = 5
destruct, Index = 3
destruct, Index = 1

赋值函数

可以用元素列表或者另一个forward_list赋值给forward_list。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::forward_list<float> tmp = {1.1f, 2.1f, 3.1f};
std::forward_list<float> f1;
std::forward_list<float> f2;

f1 = tmp;
f2 = {2.1f, 2.2f, 2.3f, 2.4f};
print_func(f1);
print_func(f2);

输出结果:

bash 复制代码
1.1 2.1 3.1 
2.1 2.2 2.3 2.4 

assign

将值赋值给forward_list,可以是元素、元素列表或者迭代器。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<float> vec(10, 1.2f);
std::forward_list<float> f;

f.assign(5, 1.2);
print_func(f);
f.assign(vec.begin(), vec.end());
print_func(f);
f.assign({1.1f, 2.1f, 3.1f});
print_func(f);

输出结果:

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::forward_list<float> f = {1.f, 2.f, 3.f};
f.front() = 4.1f;
std::cout << "f front is: " << f.front() << std::endl;

输出结果:

bash 复制代码
f front is: 4.1

迭代器

before_begin和cbefore_begin返回forward_list开头之前的迭代器,begin和cbegin返回forward_list起始的迭代器,end和cend返回forward_list末尾的迭代器。代码示例:

cpp 复制代码
std::forward_list<float> f = {1.f, 2.f, 3.f};
for (auto iter = f.begin(); iter != f.end(); ++iter)
{
    *iter += 1.1f;
}

for (auto iter = f.cbegin(); iter != f.cend(); ++iter)
{
    std::cout << "num is: " << *iter << std::endl;
}

输出结果:

bash 复制代码
num is: 2.1
num is: 3.1
num is: 4.1

容量

empty

检查forward_list是否为空。代码示例:

cpp 复制代码
std::forward_list<float> f1;
std::forward_list<float> f2 = {1.f, 2.f, 3.f};
std::cout << std::boolalpha;
std::cout << "f1 empty: " << f1.empty() << std::endl;
std::cout << "f2 empty: " << f2.empty() << std::endl;

输出结果:

bash 复制代码
f1 empty: true
f2 empty: false

max_size

返回可以容纳的最大元素个数。代码示例:

cpp 复制代码
struct MyStruct
{
    double num1;
    double num2;
    double num3;
    double num4;
};

std::forward_list<float> f1;
std::forward_list<double> f2;
std::forward_list<MyStruct> f3;
std::cout << "f1 max size = " << f1.max_size() << std::endl;
std::cout << "f2 max size = " << f2.max_size() << std::endl;
std::cout << "f3 max size = " << f3.max_size() << std::endl;

输出结果:

bash 复制代码
f1 max size = 1152921504606846975
f2 max size = 1152921504606846975
f3 max size = 461168601842738790

修改器

clear

清除所有的元素。代码示例:

cpp 复制代码
std::forward_list<float> f(3, 1.f);
std::cout << std::boolalpha;
std::cout << "f empty: " << f.empty() << std::endl;
f.clear();
std::cout << "f empty: " << f.empty() << std::endl;

输出结果:

bash 复制代码
f empty: false
f empty: true

insert_after

在指定位置后面插入元素。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<float> tmp = {11.1f, 11.2f, 11.3f};
std::forward_list<float> f = {1.1f};
auto pos = f.insert_after(f.begin(), 2.1f);
print_func(f);
f.insert_after(pos, 3, 3.1f);
print_func(f);
pos = f.insert_after(f.begin(), tmp.begin(), tmp.end());
print_func(f);
f.insert_after(pos, {25.1f, 25.2f});
print_func(f);

输出结果:

bash 复制代码
1.1 2.1 
1.1 2.1 3.1 3.1 3.1 
1.1 11.1 11.2 11.3 2.1 3.1 3.1 3.1 
1.1 11.1 11.2 11.3 25.1 25.2 2.1 3.1 3.1 3.1 

emplace_after

在指定位置后面构造一个元素。代码示例:

cpp 复制代码
struct MyStruct
{
    MyStruct(float num1, int num2)
    {
        std::cout << "construct " << num1 << " " << num2 << std::endl;
    }
};

std::forward_list<MyStruct> f;
f.emplace_after(f.before_begin(), 1.4f, 2);
f.emplace_after(f.before_begin(), 3.2f, 5);

输出结果:

bash 复制代码
construct 1.4 2
construct 3.2 5

erase_after

移除指定位置后面的元素或者移除某个范围内的元素。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::forward_list<float> f = {1.5f, 2.5f, 3.5f, 4.5f, 5.5f};
f.erase_after(f.begin());
print_func(f);
f.erase_after(f.begin(), std::next(f.begin(), 3));
print_func(f);

输出结果:

bash 复制代码
1.5 3.5 4.5 5.5 
1.5 5.5 

push_front

在起始位置插入一个元素。代码示例:

cpp 复制代码
std::forward_list<float> f = {1.1f, 2.1f};
std::cout << "f front is: " << f.front() << std::endl;
f.push_front(3.1f);
std::cout << "f front is: " << f.front() << std::endl;

输出结果:

bash 复制代码
f front is: 1.1
f front is: 3.1

emplace_front

在起始位置构造一个元素。代码示例:

cpp 复制代码
struct MyStruct
{
    MyStruct(float num1, int num2)
    {
        std::cout << "construct " << num1 << " " << num2 << std::endl;
    }
};

std::forward_list<MyStruct> f;
f.emplace_front(2.1f, 5);
f.emplace_front(2.5f, 3);

输出结果:

bash 复制代码
construct 2.1 5
construct 2.5 3

pop_front

移除forward_list的首个元素。代码示例:

cpp 复制代码
std::forward_list<float> f = {1.1f, 2.1f, 3.1f};
std::cout << "f front is: " << f.front() << std::endl;
f.pop_front();
std::cout << "f front is: " << f.front() << std::endl;

输出结果:

bash 复制代码
f front is: 1.1
f front is: 2.1

resize

重新设置元素的个数。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::forward_list<float> f = {1.1f, 2.1f, 3.1f, 4.1f};
print_func(f);
f.resize(2);
print_func(f);

输出结果:

bash 复制代码
1.1 2.1 3.1 4.1 
1.1 2.1 

swap

和另一个forward_list交换元素内容。代码示例:

cpp 复制代码
std::forward_list<float> f1 = {1.1f, 2.1f, 3.1f};
std::forward_list<float> f2 = {11.5f, 12.5f, 13.5f, 14.5f};
f1.swap(f2);
std::cout << "f1 front is: " << f1.front() << std::endl;
std::cout << "f2 front is: " << f2.front() << std::endl;

输出结果:

bash 复制代码
f1 front is: 11.5
f2 front is: 1.1

操作

sort

对元素进行排序。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::forward_list<int> f = {5, 2, 18, 9};
print_func(f);

f.sort();
print_func(f);

f.sort(
    [](int a, int b)
    {
        return a > b;
    });
print_func(f);

输出结果:

bash 复制代码
5 2 18 9 
2 5 9 18 
18 9 5 2 

merge

合并两个有序的列表。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

{
    std::forward_list<int> f1 = {1, 5, 7, 19};
    std::forward_list<int> f2 = {2, 3, 14, 15};
    f1.merge(f2);
    print_func(f1);
}

{
    std::forward_list<int> f1 = {1, 5, 7, 19};
    std::forward_list<int> f2 = {2, 3, 14, 15};
    f1.merge(f2,
             [](int a, int b)
             {
                 return a > b;
             });
    print_func(f1);
}

输出结果:

bash 复制代码
1 2 3 5 7 14 15 19 
2 3 14 15 1 5 7 19 

splice_after

将另一个列表中的一些元素移动到this列表指定的位置。代码示例:

cpp 复制代码
auto print_func = [](std::string tag, const std::forward_list<float>& list)
{
    std::cout << tag;
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

{
    std::forward_list<float> f1 = {1.5f, 5.5f, 7.5f, 19.5f};
    std::forward_list<float> f2 = {2.4f, 3.4f, 14.4f, 15.4f};
    f1.splice_after(f1.begin(), f2);
    print_func("f1 = ", f1);
    print_func("f2 = ", f2);
}

{
    std::forward_list<float> f1 = {1.5f, 5.5f, 7.5f, 19.5f};
    std::forward_list<float> f2 = {2.4f, 3.4f, 14.4f, 15.4f};
    f1.splice_after(std::next(f1.begin(), 2), f2, std::next(f2.begin(), 1));
    print_func("f1 = ", f1);
    print_func("f2 = ", f2);
}

{
    std::forward_list<float> f1 = {1.5f, 5.5f, 7.5f, 19.5f};
    std::forward_list<float> f2 = {2.4f, 3.4f, 14.4f, 15.4f};
    f1.splice_after(f1.begin(), f2, f2.begin(), std::next(f2.begin(), 2));
    print_func("f1 = ", f1);
    print_func("f2 = ", f2);
}

输出结果:

bash 复制代码
f1 = 1.5 2.4 3.4 14.4 15.4 5.5 7.5 19.5 
f2 = 
f1 = 1.5 5.5 7.5 14.4 19.5 
f2 = 2.4 3.4 15.4 
f1 = 1.5 3.4 5.5 7.5 19.5 
f2 = 2.4 14.4 15.4 

remove、remove_if

remove移除等于指定值的元素。remove_if移除满足指定要求的元素。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::forward_list<int> f = {5, 9, 17, 27, 15, 5, 5};
print_func(f);

f.remove(5);
print_func(f);

f.remove_if(
    [](int n)
    {
        return n > 15;
    });
print_func(f);

输出结果:

bash 复制代码
5 9 17 27 15 5 5 
9 17 27 15 
9 15 

reverse

反转元素的顺序。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::forward_list<float> f = {1.1f, 3.1f, 19.1f, 7.1f};
print_func(f);
f.reverse();
print_func(f);

输出结果:

bash 复制代码
1.1 3.1 19.1 7.1 
7.1 19.1 3.1 1.1 

unique

删除连续的重复元素。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::forward_list<int> f = {1, 3, 3, 17, 7, 3, 17, 17, 19, 1, 3, 1};
print_func(f);
f.unique();
print_func(f);

输出结果:

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::forward_list<int> f1 = {1, 2, 3, 4};
std::forward_list<int> f2 = {1, 5};
std::cout << std::boolalpha;
std::cout << "f1 == f2: " << (f1 == f2) << std::endl;
std::cout << "f1 != f2: " << (f1 != f2) << std::endl;
std::cout << "f1 <  f2: " << (f1 < f2) << std::endl;
std::cout << "f1 <= f2: " << (f1 <= f2) << std::endl;
std::cout << "f1 >  f2: " << (f1 > f2) << std::endl;
std::cout << "f1 >= f2: " << (f1 >= f2) << std::endl;

输出结果:

bash 复制代码
f1 == f2: false
f1 != f2: true
f1 <  f2: true
f1 <= f2: true
f1 >  f2: false
f1 >= f2: false

swap

交换两个列表的元素内容。示例代码:

cpp 复制代码
std::forward_list<float> f1 = {1.5f, 2.5f};
std::forward_list<float> f2 = {17.1f, 15.1f, 27.1f};
std::swap(f1, f2);
std::cout << "f1 front is: " << f1.front() << std::endl;
std::cout << "f2 front is: " << f2.front() << std::endl;

输出结果:

bash 复制代码
f1 front is: 17.1
f2 front is: 1.5

erase、erase_if

erase删除等于指定值的元素,erase_if删除满足条件的元素。代码示例:

cpp 复制代码
auto print_func = [](const std::forward_list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::forward_list<int> f = {5, 7, 17, 29, 7, 7, 35};
print_func(f);

std::erase(f, 7);
print_func(f);

std::erase_if(f,
              [](int a)
              {
                  return a > 17;
              });
print_func(f);

输出结果:

bash 复制代码
5 7 17 29 7 7 35 
5 17 29 35 
5 17 
相关推荐
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
versatile_zpc5 小时前
C++初阶:类和对象(上)
开发语言·c++
小鱼仙官6 小时前
MFC IDC_STATIC控件嵌入一个DIALOG界面
c++·mfc
神仙别闹6 小时前
基本MFC类框架的俄罗斯方块游戏
c++·游戏·mfc
娅娅梨6 小时前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
兵哥工控6 小时前
MFC工控项目实例二十九主对话框调用子对话框设定参数值
c++·mfc
我爱工作&工作love我6 小时前
1435:【例题3】曲线 一本通 代替三分
c++·算法
娃娃丢没有坏心思7 小时前
C++20 概念与约束(2)—— 初识概念与约束
c语言·c++·现代c++
lexusv8ls600h7 小时前
探索 C++20:C++ 的新纪元
c++·c++20