名稱空間
變體
操作

C++ 命名要求: SequenceContainer

來自 cppreference.com
 
 
C++ 命名要求
基本
型別屬性
全庫範圍




Container(容器)
SequenceContainer(序列容器)
容器元素
迭代器 (Iterator)
流 I/O
格式化器
(C++20)
隨機數
併發
(C++11)
Ranges
多維檢視
其他

 

SequenceContainer 是一種 Container,它以線性排列儲存相同型別的物件。

目錄

[編輯] 要求

給定以下型別和值:

型別 定義
C 序列容器類
T C 的元素型別
A C 的分配器型別
  • 如果存在,則為 C::allocator_type
  • 否則為 std::allocator<T>
R (從 C++23 開始) 模擬 container-compatible-range <T> 的型別
Args (從 C++11 開始) 模板引數包
Iter C::iterator
Ref C::reference
CRef C::const_reference
定義
v 型別為 C 的值
cv 型別為 const C 的值
i, j LegacyInputIterators,使得 [ij) 是一個 有效範圍,並且迭代器引用隱式可轉換為 C::value_type 的元素
rg (從 C++23 開始) 型別為 R 的值
il (從 C++11 開始) 型別為 std::initializer_list<C::value_type> 的值
n 型別為 C::size_type 的值
p 指向 v 中的有效 const 迭代器
q 指向 v 中的 有效可解引用 const 迭代器
q1, q2 指向 v 中的 const 迭代器,使得 [q1q2) 是一個有效範圍
t 型別為 C::value_type 的值(直到 C++11)型別為 C::value_type左值 或 const 右值(從 C++11 開始)
rv (從 C++11 開始) 型別為 C::value_type 的非 const 右值
args (從 C++11 開始) 模式為 Arg&& 的函式引數包

如果滿足以下所有條件,則 C 滿足 SequenceContainer 的要求:

  • C 滿足 Container 的要求。
  • 以下語句和表示式格式良好並具有指定語義:
基本操作
(所有 標準庫 中的序列容器都要求這樣做,除了 std::array(從 C++11 開始))
語句     語義[1]
C c(n, t); 效果 構造一個序列容器,其中包含 nt 的副本。
前置條件

T 可以 CopyInsertableC 中。

(C++11 起)
後置條件  std::distance(c.begin(), c.end())n
C c(i, j); 效果 構造一個序列容器,其元素與範圍 [ij) 逐元素相等。
  • 範圍 [ij) 中的每個迭代器被解引用一次。
前置條件

T 可以從 *i EmplaceConstructibleC 中。

(C++11 起)
後置條件 std::distance(c.begin(), c.end()) 等於 std::distance(i, j)
表示式  型別  語義
C(std::from_range, rg)
(C++23 起)
C 效果 構造一個序列容器,其元素與範圍 rg 逐元素相等。
  • 範圍 rg 中的每個迭代器被解引用一次。
前置條件 T 可以從 *ranges::begin(rg) EmplaceConstructibleX 中。
後置條件 std::distance(begin(), end()) 等於 ranges::distance(rg)
C(il)
(C++11 起)
C 等價於 C(il.begin(), il.end())
v = il
(C++11 起)
C& 效果 il 所表示的範圍賦值給 v[2]
返回值 *this
前置條件 T 可以 CopyInsertableC 中,並且可以 CopyAssignable
後置條件 v 的現有元素被銷燬或賦值。
v.emplace(p, args)
(C++11 起)
Iter  效果 p 之前插入一個用 std::forward<Args>(args)... 構造的 T 型別物件。
返回值 指向從 args 構造到 v 中的新元素的迭代器。
前置條件 T 可以從 args EmplaceConstructibleC 中。
v.insert(p, t) Iter 效果 p 之前插入 t 的一個副本。
返回值 指向插入到 v 中的 t 副本的迭代器。
前置條件

T 可以 CopyInsertableC 中。

(C++11 起)
v.insert(p, rv)
(C++11 起)
Iter 效果 p 之前插入 rv 的一個副本,可能使用移動語義。
返回值 指向插入到 v 中的 rv 副本的迭代器。
前置條件 T 可以 MoveInsertableC 中。
v.insert(p, n, t) Iter 效果 p 之前插入 nt 的副本。
返回值 指向插入到 v 中的第一個元素副本的迭代器,如果 n0,則為 p
前置條件

T 可以 CopyInsertableC 中,並且可以 CopyAssignable

(C++11 起)
v.insert(p, i, j) Iter 效果 p 之前插入範圍 [ij) 中元素的副本。
  • 範圍 [ij) 中的每個迭代器被解引用一次。
返回值 指向插入到 v 中的第一個元素副本的迭代器,如果 i == jtrue,則為 p
前置條件
(C++11 起)
  • ij 不在 v 中。
v.insert_range(p, rg)
(C++23 起)
Iter 效果 p 之前插入 rg 中元素的副本。
  • 範圍 rg 中的每個迭代器被解引用一次。
返回值 指向插入到 v 中的第一個元素副本的迭代器,如果 rg 為空,則為 p
前置條件
v.insert(p, il)
(C++11 起)
Iter 等價於 v.insert(p, il.begin(), il.end())
v.erase(q) Iter 效果 擦除 q 指向的元素。
返回值 指向在元素被擦除之前緊跟在 q 後面的元素的迭代器,如果不存在這樣的元素,則為 v.end()
v.erase(q1, q2) Iter 效果 擦除範圍 [q1q2) 中的元素。
返回值 指向在任何元素被擦除之前由 q2 指向的元素的迭代器,如果不存在這樣的元素,則為 v.end()
v.clear() void 效果 銷燬 v 中的所有元素。
  • 使所有引用 v 元素的引用、指標和迭代器失效,並可能使 past-the-end 迭代器失效。
後置條件 v.empty()true
複雜度 線性。
v.assign(i, j) void 效果 v 中的元素替換為範圍 [ij) 的副本。
  • 使所有引用 v 元素的引用、指標和迭代器失效。
  • 範圍 [ij) 中的每個迭代器被解引用一次。
前置條件
(C++11 起)
  • ij 不在 v 中。
v.assign_range(rg)
(C++23 起)
void 效果 v 中的元素替換為 rg 中每個元素的副本。
前置條件
v.assign(il)
(C++11 起)
void 等價於 v.assign(il.begin(), il.end())
v.assign(n, t) void 效果 v 中的元素替換為 nt 的副本。
前置條件

T 可以 CopyInsertableC 中,並且可以 CopyAssignable

(C++11 起)
    額外操作[3]
(僅適用於指定的序列容器,省略 std::)
表示式  型別  語義
v.front() Ref 容器 basic_string, array, vector, inplace_vector, deque, list, forward_list
返回值 *v.begin()
cv.front() CRef 容器 basic_string, array, vector, inplace_vector, deque, list, forward_list
返回值 *cv.begin()
v.back() Ref 容器 basic_string, array, vector, inplace_vector, deque, list
等價於 auto tmp = v.end(); --tmp; return *tmp;[4]
cv.back() CRef 容器 basic_string, array, vector, inplace_vector, deque, list
等價於 auto tmp = cv.end(); --tmp; return *tmp;[5]
v.emplace_front(args)
(C++11 起)
void 容器 deque, list, forward_list
效果 預先新增一個用 std::forward<Args>(args)... 構造的 T 型別物件。
返回值 v.front()
前置條件 T 可以從 args EmplaceConstructibleC 中。
v.emplace_back(args)
(C++11 起)
void 容器 vector, inplace_vector, deque, list
效果 追加一個用 std::forward<Args>(args)... 構造的 T 型別物件。
返回值 v.back()
前置條件 T 可以從 args EmplaceConstructibleC 中。
v.push_front(t) void 容器 deque, list, forward_list
效果 預先新增 t 的一個副本。
前置條件

T 可以 CopyInsertableC 中。

(C++11 起)
v.push_front(rv)
(C++11 起)
void 容器 deque, list, forward_list
效果 預先新增 rv 的一個副本,可能使用移動語義。
前置條件 T 可以 MoveInsertableC 中。
v.prepend_range(rg)
(C++23 起)
void 容器 deque, list, forward_list
效果 v.begin() 之前[6] 插入 rg 中元素的副本。
  • 範圍 rg 中的每個迭代器被解引用一次。
前置條件 T 可以從 *ranges::begin(rg) EmplaceConstructibleC 中。
v.push_back(t) void 容器 basic_string, vector, inplace_vector, deque, list
效果 追加 t 的一個副本。
前置條件

T 可以 CopyInsertableC 中。

(C++11 起)
v.push_back(rv)
(C++11 起)
void 容器 basic_string, vector, inplace_vector, deque, list
效果 追加 rv 的一個副本,可能使用移動語義。
前置條件 T 可以 MoveInsertableC 中。
v.append_range(rg)
(C++23 起)
void 容器 vector, inplace_vector, deque, list
效果 v.end() 之前[6] 插入 rg 中元素的副本。
  • 範圍 rg 中的每個迭代器被解引用一次。
前置條件 T 可以從 *ranges::begin(rg) EmplaceConstructibleC 中。
v.pop_front() void 容器 deque, list, forward_list
效果 銷燬第一個元素。
前置條件 a.empty()false
v.pop_back() void 容器 basic_string, vector, inplace_vector, deque, list
效果 銷燬最後一個元素。
前置條件 a.empty()false
v[n] Ref 容器 basic_string, array, vector, inplace_vector, deque
等價於 return *(v.begin() + n);
cv[n] CRef 容器 basic_string, array, vector, inplace_vector, deque
等價於 return *(cv.begin() + n);
v.at(n) Ref 容器 basic_string, array, vector, inplace_vector, deque
返回值 *(v.begin() + n)
異常 如果 n >= v.size()true,則丟擲 std::out_of_range
cv.at(n) CRef 容器 basic_string, array, vector, inplace_vector, deque
返回值 *(cv.begin() + n)
異常 如果 n >= cv.size()true,則丟擲 std::out_of_range
注意
  1. 對於效果等同於某些其他操作的表示式,這些操作內部表示式的條件將繼承到表中列出的條件之上。
  2. std::array 支援從 大括號括起來的初始化列表 賦值,但不支援從 std::initializer_list 賦值。
  3. 以下所有操作,除了 prepend_rangeappend_range(從 C++23 開始),都採用攤銷常數時間。
  4. 在 C++98 中,tmp 被宣告為 C::iterator 型別。
  5. 在 C++98 中,tmp 被宣告為 C::const_iterator 型別。
  6. 6.0 6.1 插入順序相對於 rg 中元素的順序是非反轉的。

此外,對於每個序列容器:

  • 接受兩個輸入迭代器的建構函式模板以及接受兩個輸入迭代器的 insertappendassignreplace 成員函式模板過載,如果相應的模板引數不滿足 LegacyInputIterator,則不參與過載決議。
  • 如果為具有 LegacyInputIteratorAllocator 模板引數的推導指南推匯出的型別不符合輸入迭代器或分配器的條件,則該推導指南不參與過載決議。
(C++17 起)

[編輯] 標準庫

以下標準庫字串型別和容器滿足 SequenceContainer 的要求:

儲存和操作字元序列
(類模板) [編輯]
(C++11)
固定大小的原位連續陣列
(類模板) [編輯]
可變大小的連續陣列
(類模板) [編輯]
可變大小、固定容量、原地連續陣列
(類模板) [編輯]
雙端佇列
(類模板) [編輯]
單向連結串列
(類模板) [編輯]
雙向連結串列
(類模板) [編輯]

[編輯] 使用說明

Container(容器) 優點 缺點
std::vector 快速訪問,連續儲存 插入/刪除效率大多低下
std::inplace_vector 快速訪問,就地連續儲存 固定容量,插入/刪除效率大多低下
std::array 快速訪問,就地連續儲存 固定數量的元素,無插入/刪除
std::deque 快速訪問,在開頭/結尾高效插入/刪除 在序列中間插入/刪除效率低下
std::list
std::forward_list
在序列中間高效插入/刪除 訪問大多是線性時間

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 139 C++98 可選操作不需要
為指定容器實現
要求攤銷時間
LWG 149 C++98 v.insert(p, t) 返回 Iter,而
v.insert(p, n, t)v.insert(p, n, t) 返回 void
它們都返回 Iter
LWG 151 C++98 q1 被要求是可解引用的[1] 它可以是不可解引用的
LWG 355 C++98 呼叫 v.back()v.pop_back()
執行 --v.end(),這很危險[2]
遞減 v.end() 的副本
而不是直接遞減
LWG 589 C++98 ij 引用的元素
可能無法轉換為 C::value_type
它們被隱式地
轉換為 C::value_type
LWG 2194 C++11 std::queuestd::priority_queue
std::stack 也曾是 SequenceContainers[3]
它們不是 SequenceContainers
LWG 2231 C++11 v.clear() 的複雜度要求
在 C++11 中被錯誤地省略了
複雜度重新確認為線性
LWG 3927 C++98 operator[] 沒有隱式要求 添加了隱式要求
  1. 這是一個缺陷,因為它使得如果 v 是一個空容器,那麼 v.erase(v.begin(), v.end()) 的行為是未定義的。
  2. 如果 v.end() 的型別是基本型別,那麼 --v.end() 是不合法的。當 v 的型別是模板化的,在這種情況下,這個錯誤很難被發現,這很危險。
  3. 在 C++98 中,它們沒有被記錄為 SequenceContainer