C++ 命名要求: SequenceContainer
來自 cppreference.com
SequenceContainer 是一種 Container,它以線性排列儲存相同型別的物件。
目錄 |
[編輯] 要求
給定以下型別和值:
型別 | 定義 |
C
|
序列容器類 |
T
|
C 的元素型別 |
A
|
C 的分配器型別
|
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,使得 [ i, j) 是一個 有效範圍,並且迭代器引用隱式可轉換為 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 迭代器,使得 [ q1, q2) 是一個有效範圍 |
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); | 效果 | 構造一個序列容器,其中包含 n 個 t 的副本。 | |
前置條件 |
| ||
後置條件 | std::distance(c.begin(), c.end()) 為 n。 | ||
C c(i, j); | 效果 | 構造一個序列容器,其元素與範圍 [ i, j) 逐元素相等。
| |
前置條件 |
| ||
後置條件 | std::distance(c.begin(), c.end()) 等於 std::distance(i, j)。 | ||
表示式 | 型別 | 語義 | |
C(std::from_range, rg) (C++23 起) |
C
|
效果 | 構造一個序列容器,其元素與範圍 rg 逐元素相等。
|
前置條件 | T 可以從 *ranges::begin(rg) EmplaceConstructible 到 X 中。 | ||
後置條件 | 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 可以 CopyInsertable 到 C 中,並且可以 CopyAssignable。 | ||
後置條件 | v 的現有元素被銷燬或賦值。 | ||
v.emplace(p, args) (C++11 起) |
Iter
|
效果 | 在 p 之前插入一個用 std::forward<Args>(args)... 構造的 T 型別物件。 |
返回值 | 指向從 args 構造到 v 中的新元素的迭代器。 | ||
前置條件 | T 可以從 args EmplaceConstructible 到 C 中。 | ||
v.insert(p, t) | Iter
|
效果 | 在 p 之前插入 t 的一個副本。 |
返回值 | 指向插入到 v 中的 t 副本的迭代器。 | ||
前置條件 |
| ||
v.insert(p, rv) (C++11 起) |
Iter
|
效果 | 在 p 之前插入 rv 的一個副本,可能使用移動語義。 |
返回值 | 指向插入到 v 中的 rv 副本的迭代器。 | ||
前置條件 | T 可以 MoveInsertable 到 C 中。 | ||
v.insert(p, n, t) | Iter
|
效果 | 在 p 之前插入 n 個 t 的副本。 |
返回值 | 指向插入到 v 中的第一個元素副本的迭代器,如果 n 是 0,則為 p。 | ||
前置條件 |
| ||
v.insert(p, i, j) | Iter
|
效果 | 在 p 之前插入範圍 [ i, j) 中元素的副本。
|
返回值 | 指向插入到 v 中的第一個元素副本的迭代器,如果 i == j 為 true,則為 p。 | ||
前置條件 |
| ||
v.insert_range(p, rg) (C++23 起) |
Iter
|
效果 | 在 p 之前插入 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
|
效果 | 擦除範圍 [ q1, q2) 中的元素。 |
返回值 | 指向在任何元素被擦除之前由 q2 指向的元素的迭代器,如果不存在這樣的元素,則為 v.end()。 | ||
v.clear() | void | 效果 | 銷燬 v 中的所有元素。
|
後置條件 | v.empty() 為 true。 | ||
複雜度 | 線性。 | ||
v.assign(i, j) | void | 效果 | 將 v 中的元素替換為範圍 [ i, j) 的副本。
|
前置條件 |
| ||
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 中的元素替換為 n 個 t 的副本。 |
前置條件 |
| ||
額外操作[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 EmplaceConstructible 到 C 中。 | ||
v.emplace_back(args) (C++11 起) |
void | 容器 | vector, inplace_vector, deque, list
|
效果 | 追加一個用 std::forward<Args>(args)... 構造的 T 型別物件。 | ||
返回值 | v.back() | ||
前置條件 | T 可以從 args EmplaceConstructible 到 C 中。 | ||
v.push_front(t) | void | 容器 | deque, list, forward_list
|
效果 | 預先新增 t 的一個副本。 | ||
前置條件 |
| ||
v.push_front(rv) (C++11 起) |
void | 容器 | deque, list, forward_list
|
效果 | 預先新增 rv 的一個副本,可能使用移動語義。 | ||
前置條件 | T 可以 MoveInsertable 到 C 中。 | ||
v.prepend_range(rg) (C++23 起) |
void | 容器 | deque, list, forward_list
|
效果 | 在 v.begin() 之前[6] 插入 rg 中元素的副本。
| ||
前置條件 | T 可以從 *ranges::begin(rg) EmplaceConstructible 到 C 中。 | ||
v.push_back(t) | void | 容器 | basic_string, vector, inplace_vector, deque, list
|
效果 | 追加 t 的一個副本。 | ||
前置條件 |
| ||
v.push_back(rv) (C++11 起) |
void | 容器 | basic_string, vector, inplace_vector, deque, list
|
效果 | 追加 rv 的一個副本,可能使用移動語義。 | ||
前置條件 | T 可以 MoveInsertable 到 C 中。 | ||
v.append_range(rg) (C++23 起) |
void | 容器 | vector, inplace_vector, deque, list
|
效果 | 在 v.end() 之前[6] 插入 rg 中元素的副本。
| ||
前置條件 | T 可以從 *ranges::begin(rg) EmplaceConstructible 到 C 中。 | ||
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。 | ||
注意 | |||
|
此外,對於每個序列容器:
- 接受兩個輸入迭代器的建構函式模板以及接受兩個輸入迭代器的
insert
、append
、assign
、replace
成員函式模板過載,如果相應的模板引數不滿足 LegacyInputIterator,則不參與過載決議。
|
(C++17 起) |
[編輯] 標準庫
以下標準庫字串型別和容器滿足 SequenceContainer 的要求:
儲存和操作字元序列 (類模板) | |
(C++11) |
固定大小的原位連續陣列 (類模板) |
可變大小的連續陣列 (類模板) | |
(C++26) |
可變大小、固定容量、原地連續陣列 (類模板) |
雙端佇列 (類模板) | |
(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 | 由 i 和 j 引用的元素 可能無法轉換為 C::value_type |
它們被隱式地 轉換為 C::value_type |
LWG 2194 | C++11 | std::queue、std::priority_queue 和 std::stack 也曾是 SequenceContainers[3] |
它們不是 SequenceContainers |
LWG 2231 | C++11 | v.clear() 的複雜度要求 在 C++11 中被錯誤地省略了 |
複雜度重新確認為線性 |
LWG 3927 | C++98 | operator[] 沒有隱式要求 | 添加了隱式要求 |