【C++学習|初心者向け】メモリを節約したいならこれ!std::forward_listの基本と使いどころ

1. 導入:なぜstd::forward_listが必要なのか

C++でデータをリスト形式で管理したいとき、多くの方が std::vector や std::list を思い浮かべるでしょう。しかし、要素がそれほど多くない場合や、メモリ使用量を極限まで抑えたいという場面では、これらは「少し贅沢」かもしれません。
そこで登場するのが std::forward_list です。これは「単方向リンクリスト」と呼ばれるデータ構造で、メモリ効率を最優先した設計になっています。この記事では、std::forward_listの仕組みと、賢い使い方を解説します。

2. 基礎知識:単方向リンクリストとは?

一般的な std::list(双方向リンクリスト)は、各要素が「前の要素」と「次の要素」の両方へのポインタを持っています。これにより双方向の移動が可能ですが、その分ポインタが2つ必要となり、メモリを消費します。
一方、std::forward_list は「次の要素」へのポインタしか持ちません。これが「単方向」という名前の由来です。
・メリット:メモリ消費量が極めて小さい。
・デメリット:逆方向に辿ることはできない。また、末尾へのアクセスや追加は苦手。
この「割り切り」こそが、std::forward_list の最大の強みです。

3. 実装/解決策:基本的な操作手順

std::forward_list は、「先頭」に対する操作が非常に高速です。要素の追加・削除は、先頭(push_front)に行うのが基本ルールです。途中に要素を挿入したい場合は、イテレータを使って直前の要素を指定して行います。

4. サンプルプログラム

以下のコードは、std::forward_list の基本的な作成、要素の追加、全要素の走査を行う例です。そのままコピーしてコンパイルしてみてください。

include
include

int main() {
// リストの初期化
std::forward_list fl = {10, 20, 30};

// 先頭に要素を追加 (push_frontのみ利用可能)
fl.push_front(5);

// 全要素を表示
std::cout << "リストの内容: "; for (int n : fl) { std::cout << n << " "; } std::cout << std::endl; // 2番目の要素を削除する例 // begin()の次の要素を削除するには erase_after を使用します auto it = fl.begin(); fl.erase_after(it); std::cout << "削除後の内容: "; for (int n : fl) { std::cout << n << " "; } std::cout << std::endl; return 0; }

5. 応用・注意点:現場での使いどころ

std::forward_list を使う際に最も注意すべき点は、「サイズ(size())を取得できない」ことです。現在の要素数がいくつあるかを知るには、自分で最初から最後までループを回してカウントする必要があります。もし頻繁にサイズを確認する必要があるなら、std::vector を検討してください。
また、挿入や削除を行う際は insert_after や erase_after といった「~の後ろ」というメソッドを使うのが特徴です。これは、「前の要素」の情報を持たない単方向リスト特有の仕様ですので、覚えておくと現場で迷わずに済みます。メモリ制限が厳しい組み込み環境や、大量の小規模リストを扱う場合には非常に強力な武器になります。

コメント

タイトルとURLをコピーしました