C++のstd::listをマスターする:構文、関数、実践例
std::listとは
C++において、std::listは要素を双方向連結リストとして格納するシーケンスコンテナです。この構造により、任意の位置への要素の挿入や削除を定数時間で実行でき、リストを前後両方向に反復処理できます。std::vectorのような高速なランダムアクセスは提供しませんが、頻繁な挿入や削除が発生するシナリオで優れた性能を発揮します。
コンテナはアロケータを通じてメモリを自動的に管理するため、実行時に両端から動的に拡張・縮小が可能です。
なぜstd::listを使うのか
- シーケンスの任意の位置への定数時間での挿入と削除
- 要素を頻繁に移動するアルゴリズムに効率的
- コンテナのサイズが予測不能に変化する場合に最適
リストの定義
std::listを使用するには、<list>ヘッダーをインクルードします:
#include <list> // テンプレート定義 // template<class T, class Alloc = std::allocator<T>> class list;
パラメータ:
T- 格納する要素の型。コピー構築可能な型なら何でも可。Alloc- アロケータ型。デフォルトのstd::allocatorで通常は十分。
例1:基本的な反復処理
#include <iostream>
#include <list>
int main() {
std::list<int> my_list{12, 5, 10, 9};
for (int x : my_list) {
std::cout << x << '\n';
}
}
出力:

よく使うstd::list操作
| 関数 | 説明 |
|---|---|
insert() | イテレータ位置の前に要素を挿入 |
push_back() | 末尾に要素を追加 |
push_front() | 先頭に要素を追加 |
pop_front() | 最初の要素を削除 |
size() | 要素数を取得 |
front() | 最初の要素にアクセス |
back() | 最後の要素にアクセス |
reverse() | 要素の順序を反転 |
merge() | 2つのソート済みリストをマージ |
コンストラクタ
std::list()- デフォルトコンストラクタ。空のリストを作成。std::list(n)- 填充コンストラクタ。n個のデフォルト構築された要素を作成。std::list(first, last)- 範囲コンストラクタ。別の範囲から要素をコピー。std::list(const list&)- コピーコンストラクタ。std::list(list&&)- ムーブコンストラクタ。std::list(std::initializer_list<T>)- 初期化リストコンストラクタ。
例2:コンストラクタのバリエーション
#include <iostream>
#include <list>
int main() {
std::list<int> l; // 空
std::list<int> l1{10, 20, 30};
std::list<int> l2(l1.begin(), l1.end()); // 範囲コピー
std::list<int> l3(std::move(l1)); // ムーブ
std::cout << "Size of l: " << l.size() << '\n';
std::cout << "Contents of l2:\n";
for (int x : l2) std::cout << x << '\n';
std::cout << "Contents of l3:\n";
for (int x : l3) std::cout << x << '\n';
}
出力:

コンテナの特性
- シーケンス - 要素が線形順序で格納され、位置によってアクセス可能。
- 双方向連結リスト - 各ノードが前後のノードを知っており、定数時間での挿入/削除を実現。
- アロケータ対応 - 必要に応じてアロケータでメモリを要求。
要素の挿入
push_front、push_back、insertを使用してアイテムを追加します。
例3:混在する挿入操作
#include <algorithm>
#include <iostream>
#include <list>
int main() {
std::list<int> my_list{12, 5, 10, 9};
my_list.push_front(11); // 先頭
my_list.push_back(18); // 末尾
auto it = std::find(my_list.begin(), my_list.end(), 10);
if (it != my_list.end()) {
my_list.insert(it, 21); // 10の前
}
for (int x : my_list) std::cout << x << '\n';
}
出力:

要素の削除
単一要素や範囲の削除にはeraseを使用します。
例4:削除のデモンストレーション
#include <iostream>
#include <list>
int main() {
std::list<int> my_list{12, 5, 10, 9};
std::cout << "Before deletion:\n";
for (int x : my_list) std::cout << x << '\n';
my_list.erase(my_list.begin()); // 最初を削除
std::cout << "After deletion:\n";
for (int x : my_list) std::cout << x << '\n';
}
出力:

重要なポイント
std::listは双方向連結シーケンスコンテナである。- 任意の位置からの定数時間挿入/削除を提供。
- 双方向の順次走査をサポート。
- ランダムアクセスは非効率。高速なインデックスアクセスが必要なら
std::vectorを使用。 - コンストラクタ、イテレータ、アロケータ対応により、動的データセットに対応可能。
C言語
- C++演算子を徹底解説:種類、例、サンプルプログラム付き
- C++ do-while文:構文、実践例、ネストしたループ
- C++ switch文をマスター:構文、使い方、実践例
- C++動的配列の確保をマスター:コード例付き実践ガイド
- C++ポインタをマスター:概念、例、実践的応用
- C++演算子オーバーロード:コード例付き実践ガイド
- C++構造体を実例で徹底解説
- C++関数を実例で徹底解説:基本から応用まで
- C++ structとclassの違い:構文、特徴、使い分けのベストプラクティス
- Python collections.Counter:効率的なカウント、更新、演算操作
- Python list.count() 完全ガイド:実践例付きで徹底解説