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