std::deque

std::deque

介绍

成员函数

非成员函数

介绍

// deque 模板定义
template<class T, class Allocator = std::allocator<T>> class deque;

namespace pmr {    
    template <class T>
    using deque = std::deque<T, std::pmr::polymorphic_allocator<T>>;    // c++17
}
  • deque 介绍摘选自 cppreference.com 中文网 deque 介绍
  • std::deque(double-ended queue,双端队列)是有下标顺序容器,它允许在其首尾两段快速插入及删除
  • 在 deque 任一端插入或删除不会非法化指向其余元素的指针或引用
  • 在内存中的存储不是连续的,典型实现用单独分配的固定大小数组的序列,外加额外的登记,这表示下标访问必须进行二次指针解引用
  • deque 的存储按需自动扩展及收缩,扩张 std::deque 比扩张 std::vector 更优,因为它不涉及到复制既存元素到新内存位置
  • deque 典型地拥有较大的最小内存开销,只保有一个元素的 deque 必须分配其整个内部数组
  • 随机访问——常数 O(1)、在结尾或起始插入或移除元素——常数 O(1)、插入或移除元素——线性 O(n),std::deque 满足容器 (Container) 、知分配器容器 (AllocatorAwareContainer) 、序列容器 (SequenceContainer) 和可逆容器 (ReversibleContainer) 的要求
  • T 必须满足可复制赋值 (CopyAssignable) 和可复制构造 (CopyConstructible) 的要求(C++11 前),加诸元素的要求依赖于容器上进行的实际操作,泛言之,要求元素类型是完整类型并满足可擦除 (Erasable) 的要求,但许多成员函数附带了更严格的要求(C++11 起)
  • Allocator 用于获取/释放内存及构造/析构内存中元素的分配器,类型必须满足分配器 (Allocator) 的要求
  • 若 Allocator::value_type 与 T 不同则行为未定义

成员函数

构造析构
#include <deque>

int main()
{
    auto Print = [](const std::string &msg,const std::deque<int> &deq) {  // 打印
        std::cout << msg << " : ";
        for (int val : deq)
            std::cout << val << "\t";

        std::cout << "\n";
    };

    using deque_int = std::deque<int>;
    deque_int deq1;  // 默认构造函数
    Print("deq1", deq1);

    std::allocator<int> alloc;
    deque_int deq2(alloc);  // 设置分配器构造函数
    Print("deq2", deq2);

    deque_int deq3(5, 10);  // 设置元素数量及元素初始化值构造函数
    Print("deq3", deq3);

    deque_int deq4(5);  // 设置元素数量构造函数
    Print("deq4", deq4);

    deque_int deq5(deq3.begin(), deq3.end());  // 迭代器初始化构造函数
    Print("deq5", deq5);

    deque_int deq6(deq5);  // 拷贝构造函数
    Print("deq6", deq6);

    deque_int deq7(deq6, alloc);  // 拷贝构造函数,并指定分配器
    Print("deq7", deq7);

    deque_int deq8(std::move(deq7));  // 移动构造
    Print("deq8", deq8);
    Print("deq7", deq7);

    deque_int deq9(std::move(deq8), alloc);  // 移动构造,并指定分配器
    Print("deq9", deq9);
    Print("deq8", deq8);

    deque_int deq10({1,2,3,4,5});  // 初始化列表
    Print("deq10", deq10);

    deque_int deq11;
    deq11 = deq10;  // 重载赋值运算符
    Print("deq11", deq11);

    deque_int deq12;
    deq12.assign(5, 10);  // 将值赋给容器,数量和初始化值
    Print("deq12", deq12);
    deq12.assign({1,2,3,4,5});  // 将值赋给容器,初始化列表
    Print("deq12", deq12);
    deq12.assign(deq3.begin(), deq3.end());  // 将值赋给容器,迭代器
    Print("deq12", deq12);

    auto tp = deq12.get_allocator();
    std::cout << std::boolalpha << (typeid(tp) == typeid(alloc)) << std::endl;

    // 析构函数默认
    return 0;
}

输出结果:
deq1 :
deq2 :
deq3 : 10 10 10 10 10
deq4 : 0 0 0 0 0
deq5 : 10 10 10 10 10
deq6 : 10 10 10 10 10
deq7 : 10 10 10 10 10
deq8 : 10 10 10 10 10
deq7 :
deq9 : 10 10 10 10 10
deq8 :
deq10 : 1 2 3 4 5
deq11 : 1 2 3 4 5
deq12 : 10 10 10 10 10
deq12 : 1 2 3 4 5
deq12 : 10 10 10 10 10
true

元素访问
int main()
{
    using deque_int = std::deque<int>;
    deque_int deq{1,2,3,4,5};  // 初始化列表构造函数

    std::cout << "deq.at(2) : " << deq.at(2) << "\n";  // 访问指定的元素,同时进行越界检查
    std::cout << "deq[1] : " << deq[1] << "\n";  // 访问指定的元素
    std::cout << "deq.front() : " << deq.front() << "\n";  // 访问第一个元素
    std::cout << "deq.back() : " << deq.back() << "\n";  // 访问最后一个元素
    return 0;
}

输出结果:
deq.at(2) : 3
deq[1] : 2
deq.front() : 1
deq.back() : 5

迭代器
int main()
{
    using deque_int = std::deque<int>;
    deque_int deq{1,2,3,4,5};  // 初始化列表构造函数

    deque_int::iterator iter = deq.begin();   // 返回指向起始的迭代器,可读写
    for (; iter != deq.end(); iter++) {
        std::cout << *iter << "\t";
    }
    std::cout << "\n";

    deque_int::const_iterator citer = deq.cbegin();  // 返回指向起始的 const 迭代器,不可读写
    for (; citer != deq.cend(); citer++) {
        std::cout << *citer << "\t";
    }
    std::cout << "\n";

    deque_int::reverse_iterator riter = deq.rbegin();  // 返回指向末尾的逆向迭代器,可读写
    for (; riter != deq.rend(); riter++) {
        std::cout << *riter << "\t";
    }
    std::cout << "\n";

    deque_int::const_reverse_iterator criter = deq.crbegin();  // 返回指向末尾的 const 逆向迭代器,不可读写
    for (; criter != deq.crend(); criter++) {
        std::cout << *criter << "\t";
    }
    std::cout << "\n";
    return 0;
}

输出结果:
1 2 3 4 5
1 2 3 4 5
5 4 3 2 1
5 4 3 2 1

容量
int main()
{
    using deque_int = std::deque<int>;
    deque_int deq{1,2,3,4,5};  // 初始化列表构造函数

    std::cout << std::boolalpha << "deq.empty : " << deq.empty() << "\n";  // 检查容器是否为空
    std::cout << std::boolalpha << "deq.size : " << deq.size() << "\n";  // 返回容纳的元素数
    std::cout << std::boolalpha << "deq.max_size : " << deq.max_size() << "\n";  // 返回可容纳的最大元素数,和平台有关
    deq.shrink_to_fit();  // 通过释放未使用的内存减少内存的使用
    return 0;
}

输出结果:
deq.empty : false
deq.size : 5
deq.max_size : 4611686018427387903

修改器
int main()
{
    auto Print = [](const std::string &msg,const std::deque<int> &deq) {  // 打印
        std::cout << msg << " : ";
        for (int val : deq)
            std::cout << val << "\t";

        std::cout << "\n";
    };

    using deque_int = std::deque<int>;
    deque_int deq{1,2,3,4,5};  // 初始化列表构造函数
    Print("origin", deq);
    deq.clear();  // 清除内容
    Print("deq.clear", deq);
    deq.insert(deq.begin(), 5, 10);  // 插入元素,有多个重载函数,用法类似
    Print("deq.insert", deq);
    deq.emplace(deq.begin(), 100);  // 原位构造元素
    Print("deq.emplace", deq);
    deq.erase(deq.begin());  // 擦除元素
    Print("deq.erase", deq);
    deq.erase(deq.begin(), deq.begin() + 1);    // 擦除元素,重载
    Print("deq.erase", deq);
    deq.push_back(12);  // 将元素添加到容器末尾
    Print("deq.push_back", deq);
    deq.emplace_back(13);  // 在容器末尾就地构造元素
    Print("deq.emplace_back", deq);
    deq.pop_back();  // 移除末元素
    Print("deq.pop_back", deq);
    deq.push_front(14);  // 插入元素到容器起始
    Print("deq.push_front", deq);
    deq.emplace_front(15);  // 在容器头部就地构造元素
    Print("deq.emplace_front", deq);
    deq.pop_front();  // 移除首元素
    Print("deq.pop_front", deq);
    deq.resize(2);  // 改变容器中可存储元素的个数
    Print("deq.resize", deq);

    deque_int deq2;
    deq2.swap(deq);  // 交换内容
    Print("deq2", deq2);
    Print("deq.swap", deq);
    return 0;
}

输出结果:
origin : 1 2 3 4 5
deq.clear :
deq.insert : 10 10 10 10 10
deq.emplace : 100 10 10 10 10 10
deq.erase : 10 10 10 10 10
deq.erase : 10 10 10 10
deq.push_back : 10 10 10 10 12
deq.emplace_back : 10 10 10 10 12 13
deq.pop_back : 10 10 10 10 12
deq.push_front : 14 10 10 10 10 12
deq.emplace_front : 15 14 10 10 10 10 12
deq.pop_front : 14 10 10 10 10 12
deq.resize : 14 10
deq2 : 14 10
deq.swap :

非成员函数

int main()
{
    using deque_int = std::deque<int>;
    deque_int deq1{1,2,3,4,5};  // 初始化列表构造函数
    deque_int deq2{1,2,3,4,6};

    std::cout.setf(std::ios::boolalpha);
    std::cout << "deq1 == deq2 : " << (deq1 == deq2) << std::endl;
    std::cout << "deq1 != deq2 : " << (deq1 != deq2) << std::endl;
    std::cout << "deq1 > deq2 : " << (deq1 > deq2) << std::endl;
    std::cout << "deq1 >= deq2 : " << (deq1 >= deq2) << std::endl;
    std::cout << "deq1 < deq2 : " << (deq1 < deq2) << std::endl;
    std::cout << "deq1 <= deq2 : " << (deq1 <= deq2) << std::endl;
    std::cout.unsetf(std::ios::boolalpha);

    // c++20 废弃以上操作符重载,提供三路运算符 operator <=> ()
    return 0;
}

输出结果:
deq1 == deq2 : false
deq1 != deq2 : true
deq1 > deq2 : false
deq1 >= deq2 : false
deq1 < deq2 : true
deq1 <= deq2 : true

起始

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值