deque(); // (1) C++14 から
explicit deque(const Allocator& a); // (2) C++14 から
explicit deque(const Allocator& a = Allocator()); // (1), (2) : C++11 まで。C++14 で削除
explicit deque(size_type n, const T& value = T(),
const Allocator& a = Allocator()); // (3) C++03 まで。C++11 で削除
deque(size_type n, const T& value,
const Allocator& a = Allocator()); // (3) C++11 から
explicit deque(size_type n); // (4) C++11。C++14 で削除
explicit deque(size_type n,
const Allocator& a = Allocator()); // (4) C++14 から
template <class InputIterator>
deque(InputIterator first, InputIterator last,
const Allocator& a = Allocator()); // (5)
deque(const deque& x); // (6)
deque(deque&& y); // (7) C++11 から
deque(const deque& x, const Allocator& a); // (8) C++11 から
deque(deque&& y, const Allocator& a); // (9) C++11 から
deque(initializer_list<T> il,
const Allocator& a = Allocator()); // (10) C++11 から
template <container-compatible-range<T> R>
deque(from_range_t, R&& rg,
const Allocator& a = Allocator()); // (11) C++23 から
概要
deque
オブジェクトの構築
効果
deque
コンテナオブジェクトを構築し、コンストラクタの種類に応じて要素を初期化する。
- (1) : デフォルトコンストラクタ。サイズがゼロで要素を持たない空の
deque
を構築する。 - (2) : アロケータに
a
を使用して、サイズがゼロで要素を持たない空のdeque
を構築する。 - (1) + (2) : デフォルトコンストラクタ。アロケータに
a
を使用して、サイズがゼロで要素を持たない空のdeque
を構築する。 - (3) : 繰り返しシーケンスコンストラクタ。アロケータに
a
を使用して、value
のコピーをn
個要素として保持したdeque
を構築する。 - (4)
- (5) : イテレータ範囲コンストラクタ。アロケータに
a
を使用して、[first, last)
の範囲を要素としてコピーしたdeque
を構築する。 - (6) : コピーコンストラクタ。
x
と同じ要素を保持したdeque
を構築する。 - (7) : ムーブコンストラクタ。ムーブセマンティクスを使って
y
の要素でコンテナを構築する。 - (8) : コピーコンストラクタ。アロケータに
a
を使用して、x
と同じ要素を保持したdeque
を構築する。 - (9) : ムーブコンストラクタ。アロケータに
a
を使用して、ムーブセマンティクスを使ってy
の要素でコンテナを構築する。 - (10) : 初期化子リストで要素を構築するコンストラクタ。
deque(il.begin(), il.end(), a)
と等価。 - (11) : Rangeコンストラクタ。アロケータに
a
を使用して、rg
の要素でdeque
を構築する。
計算量
- (1) : 定数時間
- (2) : 定数時間
- (1) + (2) : 定数時間
- (3) :
n
に対して線形時間 - (4) :
n
に対して線形時間 - (5) :
first
からlast
への距離に対して線形時間 - (6) :
x
の要素数に対して線形時間 - (7) : 定数時間
- (8) :
x
の要素数に対して線形時間 - (9) :
a == y.get_allocator()
の場合、定数時間、そうでなければy
の要素数に対して線形時間 - (10) :
il
の要素数に対して線形時間 - (11) :
rg
の要素数に対して線形時間
備考
- イテレータ範囲コンストラクタ
template <class InputIterator> deque(InputIterator first, InputIterator last, const Allocator& a = Allocator())
は、C++03 まではInputIterator
が整数型の場合にはdeque(static_cast<typename deque::size_type>(first), static_cast<typename deque::value_type>(last), a)
と等価とされていたが、C++11 ではInputIterator
が入力イテレータの要件を満たさなければオーバーロード解決に参加しないように変更された。 -
C++11 では、
explicit deque(size_type n, const T& value = T(), const Allocator& a = Allocator())
の引数value
に関するデフォルト引数が削除され、新たなコンストラクタexplicit deque(size_type n)
が追加された。
これは、デフォルト引数を使用すると、引数value
のデフォルト初期化 1 回+deque
の要素へのコピー初期化n
回のコンストラクタ呼び出しが必要となるが、デフォルト引数でなければdeque
の要素へのデフォルト初期化n
回のコンストラクタ呼び出しで済むためである。 -
C++14 では、
explicit deque(const Allocator& a = Allocator())
がデフォルト引数を使用しない 2 つのオーバーロードに分割された。
これは、デフォルトコンストラクタにexplicit
が付いていると、std::deque<int> d = {};
のようなコード(C++11 から導入された、コピーリスト初期化によるデフォルトコンストラクタ呼び出し)がエラーになってしまうためである。
-
C++14 では、
explicit deque(size_type n)
に引数が追加され、explicit deque(size_type n, const Allocator& a = Allocator())
に変更された。
これは、変更されないとn
のみを引数にとるアロケータ使用構築(uses-allocator construction)に失敗してしまうためである。 具体的には、C++11 では以下のようなコードがエラーになってしまう。#include <list> #include <deque> #include <scoped_allocator> int main() { using di = std::deque<int>; std::list<di, std::scoped_allocator_adaptor<std::allocator<di>>> l; l.emplace_back(10u); }
例
#include <iostream>
#include <deque>
#include <utility>
template <class T>
void print(const char* name, const std::deque<T>& c)
{
std::cout << name << " : {";
for (const T& x : c) {
std::cout << x << " ";
}
std::cout << "}" << std::endl;
}
int main ()
{
// (1) : デフォルトコンストラクタ
std::deque<int> c1;
// (3) : 値1の要素を3個持つコンテナを構築
std::deque<int> c2(3, 1);
// (4) : 3個の要素を持つコンテナを構築
std::deque<int> c3(3);
// (5) : イテレータの範囲による構築
std::deque<int> c40 = {1, 2, 3}; // 構築用の一時オブジェクト(説明用)
std::deque<int> c4(c40.begin(), c40.end());
// (6) : コピー構築
std::deque<int> c5(c4);
// (7) : ムーブ構築
std::deque<int> c60 = {1, 2, 3}; // 構築用の一時オブジェクト(説明用)
std::deque<int> c6(std::move(c60));
// (10) : 初期化子リストによる構築
std::deque<int> c7 = {1, 2, 3};
print("c1", c1);
print("c2", c2);
print("c3", c3);
print("c4", c4);
print("c5", c5);
print("c6", c6);
print("c7", c7);
}
出力
c1 : {}
c2 : {1 1 1 }
c3 : {0 0 0 }
c4 : {1 2 3 }
c5 : {1 2 3 }
c6 : {1 2 3 }
c7 : {1 2 3 }
参照
- N2679 Initializer Lists for Standard Containers(Revision 1)
- (10)の経緯となる提案文書
- LWG 2193. Default constructors for standard library containers are explicit
explicit deque(const Allocator& a = Allocator())
を 2 つのオーバーロードに分割するきっかけとなったレポート - LWG 2210. Missing allocator-extended constructor for allocator-aware containers
explicit deque(size_type n)
にアロケータ引数を追加するきっかけとなったレポート
なお、Discussion の例はアロケータの型が誤っているので注意