Skip to content

Latest commit

 

History

History
224 lines (184 loc) · 9.36 KB

File metadata and controls

224 lines (184 loc) · 9.36 KB

コンストラクタ

  • list[meta header]
  • std[meta namespace]
  • list[meta class]
  • function[meta id-type]
list();                                          // (1) C++14
constexpr list();                                // (1) C++26

list(const Allocator& a);                        // (2) C++14
constexpr list(const Allocator& a);              // (2) C++26

explicit list(const Allocator& a = Allocator()); // (1), (2) C++11 まで。C++14 で削除

explicit list(size_type n, const T& value = T(),
              const Allocator& a = Allocator()); // (3) C++03 まで。C++11 で削除
list(size_type n, const T& value,
     const Allocator& a = Allocator());          // (3) C++11 から
constexpr
  list(size_type n, const T& value,
       const Allocator& a = Allocator());        // (3) C++26

explicit
  list(size_type n);                      // (4) C++11。C++14 で削除
explicit
  list(size_type n,
       const Allocator& a = Allocator()); // (4) C++14 から
constexpr explicit
  list(size_type n,
       const Allocator& a = Allocator()); // (4) C++26

template <class InputIterator>
list(InputIterator first,
     InputIterator last,
     const Allocator& a = Allocator());   // (5) C++03
template <class InputIterator>
constexpr
  list(InputIterator first,
       InputIterator last,
       const Allocator& a = Allocator()); // (5) C++26

list(const list& x);           // (6) C++03
constexpr list(const list& x); // (6) C++26

list(list&& x);           // (7) C++11
constexpr list(list&& x); // (7) C++26

list(const list& x,
     const Allocator& a);                    // (8) C++11
list(const list& x,
     const type_identity_t<Allocator>& a);   // (8) C++23
constexpr
  list(const list& x,
       const type_identity_t<Allocator>& a); // (8) C++26

list(list&& x,
     const Allocator& a);                    // (9) C++11
list(list&& x,
     const type_identity_t<Allocator>& a);   // (9) C++23
constexpr
  list(list&& x,
       const type_identity_t<Allocator>& a); // (9) C++26

list(initializer_list<T> il,
     const Allocator& a = Allocator());        // (10) C++11
constexpr
  list(initializer_list<T> il,
       const Allocator& a = Allocator());      // (10) C++26

template <container-compatible-range<T> R>
list(from_range_t, R&& rg,
     const Allocator& a = Allocator());        // (11) C++23
template <container-compatible-range<T> R>
constexpr
  list(from_range_t, R&& rg,
       const Allocator& a = Allocator());      // (11) C++26
  • type_identity_t[link /reference/type_traits/type_identity.md]
  • initializer_list[link /reference/initializer_list/initializer_list.md]
  • from_range_t[link /reference/ranges/from_range_t.md]

概要

list オブジェクトの構築

効果

  • (1) : デフォルトコンストラクタ。アロケータをデフォルト構築して、空のコンテナを作る。
  • (2) : アロケータを指定して空のコンテナを作る。
  • (3) : value のコピーを n 個要素として保持した list を構築する。
  • (4) : n 個の T() 初期化された要素を保持した list を構築する。
  • (5) : イテレータ範囲[first, last)を要素としてコピーした list を構築する。
  • (6) : コピーコンストラクタ。x と同じ要素を保持した list を構築する。
  • (7) : ムーブコンストラクタ。x の指す先を自分の領域として list を構築する。
  • (8) : アロケータを指定したコピーコンストラクタ。
  • (9) : アロケータを指定したムーブコンストラクタ。
  • (10) : 初期化子リストを受け取るコンストラクタ。list(il.begin(), il.end(), a) と等価。
  • (11) : Rangeコンストラクタ。Range rg の要素で list を構築する。

計算量

  • (1), (2) : 定数時間
  • (3), (4) : n に対して線形時間
  • (5) : distance(first, last) に対して線形時間
  • (6), (8) : x.size() に対して線形時間
  • (7) : 定数時間
  • (9) : a == x.get_allocator() であれば定数時間。そうでなければ x.size() に対して線形時間
  • (10) : il.size() に対して線形時間
  • (11) : ranges::distance(rg) に対して線形時間

備考

  • (5) の形式は、C++03 までは InputIterator が整数型の場合には list(static_cast<typename list::size_type>(first), static_cast<typename list::value_type>(last), a) と等価とされていたが、C++11 では InputIterator が入力イテレータの要件を満たさなければオーバーロード解決に参加しないように変更された。

  • C++11 では、(3) の形式の引数 value に関するデフォルト引数が削除され、新たに (4) の形式が追加された。
    これは、デフォルト引数を使用すると、引数 value のデフォルト初期化 1 回+list の要素へのコピー初期化 n 回のコンストラクタ呼び出しが必要となるが、デフォルト引数でなければ list の要素へのデフォルト初期化 n 回のコンストラクタ呼び出しで済むためである。

  • C++14 では、(1) の形式と (2) の形式がデフォルト引数を使用しない 2 つのオーバーロードに分割された。
    これは、デフォルトコンストラクタに explicit が付いていると、

    std::list<int> l = {};

    のようなコード(C++11 から導入された、コピーリスト初期化によるデフォルトコンストラクタ呼び出し)がエラーになってしまうためである。

  • C++14 では、(4) の形式に引数が追加された。
    これは、変更されないと n のみを引数にとるアロケータ使用構築(uses-allocator construction)に失敗してしまうためである。 具体的には、C++11 では以下のようなコードがエラーになってしまう。

    #include <list>
    #include <vector>
    #include <scoped_allocator>
    
    int main()
    {
      using li = std::list<int>;
      std::vector<li, std::scoped_allocator_adaptor<std::allocator<li>>> v;
      v.emplace_back(10u);
    }
    • std::scoped_allocator_adaptor[link ../../scoped_allocator/scoped_allocator_adaptor.md]
    • v.emplace_back[link /reference/vector/vector/emplace_back.md]
  • C++23 では、(8) と (9) のアロケータパラメータの型が const Allocator& から const type_identity_t<Allocator>& に変更された。 これは、クラステンプレートのテンプレート引数推論 (CTAD) の際に、コピー/ムーブ元の list から推論される Allocator と、アロケータ引数から推論される型が異なる場合に推論が失敗する問題を修正するためである。type_identity_t で包むことで、アロケータ引数が非推論コンテキストとなり、アロケータの型はコピー/ムーブ元のみから推論されるようになる。

#include <iostream>
#include <list>
#include <string>
#include <utility>

template <class T>
void print(const std::string& name, const std::list<T>& ls)
{
  std::cout << name << " : ";
  for (const T& x : ls) {
    std::cout << x << " ";
  }
  std::cout << std::endl;
}

int main ()
{
  // デフォルト構築
  std::list<int> ls1;
  ::print("ls1", ls1);

  // n 個の要素を持つリストを作成
  std::list<int> ls2(3);
  ::print("ls2", ls2);

  // n 個の指定された値を要素に持つリストを作成
  std::list<int> ls3(3, 1);
  ::print("ls3", ls3);

  // 範囲から構築
  std::list<int> ls4(ls3.begin(), ls3.end());
  ::print("ls4", ls4);

  // コピー構築
  std::list<int> ls5 = ls4;
  ::print("ls5", ls5);

  // ムーブ構築
  std::list<int> ls6 = std::move(ls5);
  ::print("ls6", ls6);

  // 初期化子リストで構築
  std::list<int> ls7 = { 1, 2, 3 };
  ::print("ls7", ls7);
}
  • std::move[link ../../utility/move.md]
  • ls3.begin()[link begin.md]
  • ls3.end()[link end.md]

出力

ls1 : 
ls2 : 0 0 0 
ls3 : 1 1 1 
ls4 : 1 1 1 
ls5 : 1 1 1 
ls6 : 1 1 1 
ls7 : 1 2 3 

参照