名前空間
変種
操作

C++ 名前付き要件: SequenceContainer

From cppreference.com
 
 
C++ 名前付き要件
 

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 LegacyInputIterator であって、[ij)有効な範囲であり、イテレータが C::value_type に暗黙的に変換可能な要素を参照しているもの
rg (C++23 以降) R 型の値
il (C++11 以降) std::initializer_list<C::value_type> 型の値
n C::size_type 型の値
p v 内の有効な const iterator
q v 内の 有効なデリファレンス可能な const iterator
q1, q2 v 内の const iterator であって、[q1q2) が有効な範囲となるもの
t (C++11 まで)lvalue または const rvalue(C++11 以降) of type C::value_type
rv (C++11 以降) C::value_type の非 const rvalue
args (C++11 以降) Arg&& のパターンを持つ関数パラメータパック

CSequenceContainer の要件を満たすのは、以下のすべての条件が満たされる場合です

  • CContainer の要件を満たします。
  • 以下のステートメントおよび式は、指定された意味論で正常に形成されます
基本的な数学関数
(標準ライブラリのすべてのシーケンスコンテナで必要ただし std::array を除く(C++11 以降))
ステートメント     意味論[1]
C c(n, t); 効果 tn 個のコピーを含むシーケンスコンテナを構築します。
事前条件

TCCopyInsertable です。

(C++11以降)
事後条件  std::distance(c.begin(), c.end())n です。
C c(i, j); 効果 範囲 [ij) と要素ごとに等しいシーケンスコンテナを構築します。
  • 範囲 [ij) 内の各イテレータはちょうど一度デリファレンスされます。
事前条件

T*i から CEmplaceConstructible です。

(C++11以降)
事後条件 std::distance(c.begin(), c.end())std::distance(i, j) です。
Expression  型  セマンティクス
C(std::from_range, rg)
(C++23から)
C 効果 範囲 rg と要素ごとに等しいシーケンスコンテナを構築します。
  • rg の各イテレータはちょうど1回逆参照されます。
事前条件 T は、*ranges::begin(rg) から XEmplaceConstructible です。
事後条件 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
事前条件 TCCopyInsertable であり、CopyAssignable です。
事後条件 v の既存の要素は破棄されるか、または代入されます。
v.emplace(p, args)
(C++11以降)
Iter  効果 std::forward<Args>(args)... で構築された T 型のオブジェクトを p の前に挿入します。
戻り値 args から構築された新しい要素を指すイテレータが v に挿入されます。
事前条件 Targs から CEmplaceConstructible です。
v.insert(p, t) Iter 効果 t のコピーを p の前に挿入します。
戻り値 v に挿入された t のコピーを指すイテレータ。
事前条件

TCCopyInsertable です。

(C++11以降)
v.insert(p, rv)
(C++11以降)
Iter 効果 rv のコピーを p の前に挿入します。ムーブセマンティクスを使用する場合があります。
戻り値 rv のコピーが v に挿入されたことを指すイテレータ。
事前条件 TCMoveInsertable です。
v.insert(p, n, t) Iter 効果 tn 個のコピーを p の前に挿入します。
戻り値 v に挿入された最初の要素のコピーを指すイテレータ、または n0 の場合は p
事前条件

TCCopyInsertable であり、CopyAssignable です。

(C++11以降)
v.insert(p, i, j) Iter 効果 範囲 [ij) の要素のコピーを p の前に挿入します。
  • 範囲 [ij) 内の各イテレータはちょうど一度デリファレンスされます。
戻り値 v に挿入された最初の要素のコピーを指すイテレータ、または i == jtrue の場合は p
事前条件
(C++11以降)
  • i および jv 内にはありません。
v.insert_range(p, rg)
(C++23から)
Iter 効果 rg の要素のコピーを p の前に挿入します。
  • rg の各イテレータはちょうど1回逆参照されます。
戻り値 v に挿入された最初の要素のコピーを指すイテレータ、または rg が空の場合は p
事前条件
v.insert(p, il)
(C++11以降)
Iter v.insert(p, il.begin(), il.end()) と同等です。
v.erase(q) Iter 効果 q が指す要素を削除します。
戻り値 削除される要素の直後に続く要素を指すイテレータ、またはそのような要素が存在しない場合は v.end()
v.erase(q1, q2) Iter 効果 範囲 [q1q2) の要素を削除します。
戻り値 要素が削除される前の q2 が指していた要素を指すイテレータ、またはそのような要素が存在しない場合は v.end()
v.clear() void 効果 v 内のすべての要素を破棄します。
  • v の要素を参照するすべての参照、ポインタ、およびイテレータを無効にし、終端後イテレータを無効にする場合があります。
事後条件 v.empty()true です。
計算量 線形。
v.assign(i, j) void 効果 v の要素を、範囲 [ij) のコピーで置き換えます。
  • v の要素を参照するすべての参照、ポインタ、およびイテレータを無効にします。
  • 範囲 [ij) 内の各イテレータはちょうど一度デリファレンスされます。
事前条件
(C++11以降)
  • i および jv 内にはありません。
v.assign_range(rg)
(C++23から)
void 効果 v の要素を、rg の各要素のコピーで置き換えます。
  • もし std::assignable_from
        <T&, ranges::range_reference_t<R>>
    がモデル化されていない場合、プログラムは不正に形成されます。
  • v の要素を参照するすべての参照、ポインタ、およびイテレータを無効にします。
  • rg の各イテレータはちょうど1回逆参照されます。
事前条件
v.assign(il)
(C++11以降)
void v.assign(il.begin(), il.end()) と同等です。
v.assign(n, t) void 効果 v の要素を、tn 個のコピーで置き換えます。
事前条件

TCCopyInsertable であり、CopyAssignable です。

(C++11以降)
    追加の操作[3]
(指定されたシーケンスコンテナに対してのみ必要、std:: は省略)
Expression  型  セマンティクス
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()
事前条件 Targs から CEmplaceConstructible です。
v.emplace_back(args)
(C++11以降)
void コンテナ vector, inplace_vector, deque, list
効果 std::forward<Args>(args)... で構築された T 型のオブジェクトを末尾に追加します。
戻り値 v.back()
事前条件 Targs から CEmplaceConstructible です。
v.push_front(t) void コンテナ deque, list, forward_list
効果 t のコピーを先頭に挿入します。
事前条件

TCCopyInsertable です。

(C++11以降)
v.push_front(rv)
(C++11以降)
void コンテナ deque, list, forward_list
効果 rv のコピーを先頭に挿入します。ムーブセマンティクスを使用する場合があります。
事前条件 TCMoveInsertable です。
v.prepend_range(rg)
(C++23から)
void コンテナ deque, list, forward_list
効果 rg の要素のコピーを v.begin() の前に挿入します。[6]
  • rg の各イテレータはちょうど1回逆参照されます。
事前条件 T は、*ranges::begin(rg) から CEmplaceConstructible です。
v.push_back(t) void コンテナ basic_string, vector, inplace_vector, deque, list
効果 t のコピーを末尾に追加します。
事前条件

TCCopyInsertable です。

(C++11以降)
v.push_back(rv)
(C++11以降)
void コンテナ basic_string, vector, inplace_vector, deque, list
効果 rv のコピーを末尾に追加します。ムーブセマンティクスを使用する場合があります。
事前条件 TCMoveInsertable です。
v.append_range(rg)
(C++23から)
void コンテナ vector, inplace_vector, deque, list
効果 rg の要素のコピーを v.end() の前に挿入します。[6]
  • rg の各イテレータはちょうど1回逆参照されます。
事前条件 T は、*ranges::begin(rg) から CEmplaceConstructible です。
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_range および append_range を除く)は、償却定数時間かかります。(C++23 以降)(C++23 以降)
  4. C++98 では、tmpC::iterator 型として宣言されていました。
  5. C++98 では、tmpC::const_iterator 型として宣言されていました。
  6. 6.0 6.1 rg 内の要素の順序に対する挿入順序は、非転置です。

さらに、すべてのシーケンスコンテナについて

  • 2つの入力イテレータを受け取るコンストラクタテンプレートと、2つの入力イテレータを受け取る insertappendassignreplace のメンバ関数テンプレートオーバーロードは、対応するテンプレート引数が LegacyInputIterator を満たさない場合、オーバーロード解決に参加しません。
  • LegacyInputIterator または Allocator テンプレートパラメータのいずれかを持つ推論ガイドは、そのパラメータに対して入力イテレータまたはアロケータとして適格でない型が推論された場合、オーバーロード解決に参加しません。
(C++17以降)

[編集] 標準ライブラリ

以下の標準ライブラリの文字列型およびコンテナは、SequenceContainer の要件を満たします

文字のシーケンスを格納し操作する
(クラステンプレート) [編集]
(C++11)
固定サイズのインプレースな連続配列
(クラステンプレート) [編集]
リサイズ可能な連続配列
(クラステンプレート) [編集]
リサイズ可能、固定容量、インプレースの連続配列
(クラステンプレート) [編集]
両端キュー
(クラステンプレート) [編集]
単方向連結リスト
(クラステンプレート) [編集]
双方向リンクリスト
(クラステンプレート) [編集]

[編集] 使用上の注意

コンテナ 長所 短所
std::vector 高速アクセス、連続ストレージ ほとんどの挿入/削除は非効率的
std::inplace_vector 高速アクセス、インプレース連続ストレージ 固定容量、ほとんどの挿入/削除は非効率的
std::array 高速アクセス、インプレース連続ストレージ 固定要素数、挿入/削除なし
std::deque 高速アクセス、先頭/末尾での効率的な挿入/削除 シーケンスの中央での挿入/削除は非効率的
std::list
std::forward_list
シーケンスの中央での効率的な挿入/削除 アクセスはほとんど線形時間

[編集] 不具合報告

以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。

DR 適用対象 公開された動作 正しい動作
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() のコピーをデクリメントします。
代わりに v.end() をデクリメントします。
LWG 589 C++98 i および j が参照する要素は
C::value_type に変換可能でない場合があります。
それらは暗黙的に
C::value_type に変換可能です。
LWG 2194 C++11 std::queue, std::priority_queue および
std::stackSequenceContainer でした。[3]
それらは SequenceContainer ではありません。
LWG 2231 C++11 v.clear() の複雑性要件
は C++11 では誤って省略されていました。
複雑性は線形であると再確認されました。
LWG 3927 C++98 operator[] には暗黙的な要件がありませんでした。 暗黙的な要件が追加されました。
  1. v.erase(v.begin(), v.end()) の動作が未定義となるのは、v が空のコンテナの場合です。これは欠陥です。
  2. v.end() の型が基本型の場合、--v.end() は不正に形成されます。v の型がテンプレートの場合、このバグは見つけにくいことがあります。
  3. C++98 では、SequenceContainer として文書化されていませんでした。
English 日本語 中文(简体) 中文(繁體)