<array> ヘッダー
編集C++の標準ライブラリには、固定サイズの配列を扱うためのクラステンプレートstd::array
が含まれています。この章では、std::array
の基本的な使い方から、C++のバージョンによる進化、および実践的な使用例までを解説します。
イントロダクション
編集<array>の概要
編集<array>
ヘッダーは、固定サイズの配列を表現するクラステンプレートstd::array
を提供します。std::array
は、C言語の配列に比べて安全で便利な機能を持っており、STL(標準テンプレートライブラリ)の他のコンテナと同様のインターフェースを提供します。
配列とstd::arrayの違い
編集C言語の配列とstd::array
の主な違いは以下の通りです:
std::array
はSTLの一部であり、STLのアルゴリズムとシームレスに統合できます。std::array
も固定サイズであり、サイズを変更することはできません。std::array
もコンパイル時にサイズが決定され、ヒープではなくスタック上に配置されます。std::array
には、範囲チェックを行うメンバー関数at()
があり、安全な要素アクセスが可能です。#
なぜstd::arrayを使用するのか
編集std::array
を使用する利点には以下の点が挙げられます:
- 安全性
- 範囲外アクセスに対するチェックが組み込まれているため、バグを減らすことができます。
- 可読性
- STLの他のコンテナと一貫したインターフェースを持つため、コードの可読性が向上します。
- パフォーマンス
- 固定サイズのため、メモリ割り当てのオーバーヘッドがなく、高速です。
歴史と変遷
編集std::arrayの導入(C++11)
編集std::array
はC++11で導入されました。それ以前のC++には固定サイズ配列の標準的なクラスが存在せず、C言語の配列を使用する必要がありました。C++11でstd::array
が導入されたことで、固定サイズ配列を安全に扱えるようになりました。
初期の機能と制限
編集C++11のstd::array
は、固定サイズの配列を表現するための基本的な機能を提供しましたが、いくつかの制限もありました。例えば、初期化リストを使用した初期化はサポートされていましたが、推論ガイドはありませんでした。
C++17以降の改善点
編集C++17では、推論ガイドが導入され、std::array
の初期化がさらに簡潔になりました。例えば、以下のようにauto
を使用して配列を初期化できます:
auto ary = std::array{2, 3, 5, 7, 11};
このように、推論ガイドにより、テンプレート引数を明示的に指定することなくstd::array
を初期化できるようになりました。
C++20でのさらなる改良点
編集C++20では、std::array
に対するさらなる改良が行われ、使い勝手が向上しました。例えば、コンパイル時の計算能力の向上や、より強力なコンパイル時チェックが追加されました。
基本的な使い方
編集std::arrayの宣言と初期化
編集std::array
は、次のように宣言して初期化できます:
std::array<int, 5> arr1; // デフォルト初期化 std::array<int, 5> arr2 = {1, 2, 3, 4, 5}; // 初期化リストを使用 std::array<int, 5> arr3 = {}; // すべての要素を0で初期化 auto ary = std::array{2, 3, 5, 7, 11}; // C++17の推論ガイドによる初期化
これにより、固定サイズの配列が宣言され、適切に初期化されます。
メンバー関数の紹介
編集基本的なメンバー関数
編集std::array
には、次のような基本的なメンバー関数があります:
size()
- 配列のサイズを返します。
max_size()
- 配列の最大サイズを返します。
empty()
- 配列が空であるかをチェックします。
#include <array> #include <iostream> auto main() -> int { std::array<int, 3> const arr = {10, 20, 30}; std::cout << arr.size() << std::endl; // 3 std::cout << arr.max_size() << std::endl; // 3 std::cout << std::boolalpha << arr.empty() << std::endl; // false }
要素アクセス関数
編集std::array
では、次の関数を使用して要素にアクセスできます:
operator[]
- インデックスで要素にアクセスします。
at()
- 範囲チェックを行って要素にアクセスします。
front()
- 先頭要素にアクセスします。
back()
- 末尾要素にアクセスします。
std::array<int, 3> arr = {10, 20, 30}; int first = arr.front(); // 10 int second = arr[1]; // 20 int last = arr.back(); // 30
イテレーターの使用
編集イテレーターの取得
編集std::array
はSTLのコンテナと同様に、イテレーターを提供します:
begin()
- 配列の先頭を指すイテレーターを返します。
end()
- 配列の終端の次を指すイテレーターを返します。
rbegin()
- 逆順の配列の先頭を指すイテレーターを返します。
rend()
- 逆順の配列の終端の次を指すイテレーターを返します。
for (auto it = arr.begin(); it != arr.end(); it++) { std::cout << *it << " "; } // 範囲ベースのforループ for (const auto& element : arr) { std::cout << element << " "; }
その他のメンバー関数
編集fill()
編集fill()
は配列のすべての要素を指定した値で埋めます:
std::array<int, 5> arr; arr.fill(5); // すべての要素を5で埋める
swap()
編集swap()
は2つの配列の内容を交換します:
std::array<int, 5> arr1 = {1, 2, 3, 4, 5}; std::array<int, 5> arr2 = {5, 4, 3, 2, 1}; arr1.swap(arr2); // arr1とarr2の内容を交換
アルゴリズムとの連携
編集std::array
は、STLのアルゴリズムとシームレスに連携できます。例えば、std::sort
を使用して配列をソートすることができます:
std::array<int, 5> arr = {5, 3, 1, 4, 2}; std::sort(arr.begin(), arr.end()); // 配列をソート for (const auto& elem : arr) { std::cout << elem << " "; // 1 2 3 4 5 }
ユーティリティ関数
編集std::getを使用した要素アクセス
編集std::get
を使用して、インデックスで要素にアクセスできます:
std::array<int, 3> arr = {10, 20, 30}; int value = std::get<1>(arr); // 20
std::tuple_sizeとstd::tuple_elementの利用
編集std::array
はタプルと互換性があり、std::tuple_size
とstd::tuple_element
を使用してサイズや要素型を取得できます:
constexpr std::size_t size = std::tuple_size<decltype(arr)>::value; // 3 using ElementType = std::tuple_element<1, decltype(arr)>::type; // int
std::arrayの利点と欠点
編集固定サイズによるメモリ効率
編集std::array
は固定サイズのため、メモリ効率が高く、ヒープのメモリ割り当てが不要です。
他方、スタック上に確保されるため極端に大きなサイズを確保するとスタックオーバーフローの原因になります。
使いやすいインターフェース
編集STLの他のコンテナと一貫したインターフェースを提供するため、使いやすく、コードの可読性が向上します。
可変サイズ配列(std::vector)との比較
編集std::array
は固定サイズであり、動的なサイズ変更が必要な場合にはstd::vector
の方が適しています。しかし、サイズが固定である場合は、std::array
の方が効率的です。
実践例と応用
編集std::arrayを使った基本的なアルゴリズム実装
編集std::array
を使用して、簡単なアルゴリズムを実装できます。例えば、要素の合計を計算する関数を作成できます:
std::array<int, 5> arr = {1, 2, 3, 4, 5}; int sum = std::accumulate(arr.begin(), arr.end(), 0); // 要素の合計を計算 std::cout << sum; // 15
多次元配列としての使用方法
編集std::array
は、多次元配列としても使用できます:
std::array<std::array<int, 3>, 3> matrix = {{ {1, 2, 3}, {4, 5, 6}, {7, 8, 9} }}; for (const auto& row : matrix) { for (const auto& element : row) { std::cout << element << " "; } std::cout << std::endl; }
まとめと練習問題
編集<array>ヘッダーの要点のまとめ
編集<array>
ヘッダーは、固定サイズの配列を安全かつ効率的に扱うためのクラステンプレートstd::array
を提供します。std::array
は、C++11以降の規格で導入され、C++17およびC++20でさらに改良されました。
練習問題
編集std::array
を使って、配列の全要素を2倍にするプログラムを書いてください。std::array
とstd::vector
を比較し、それぞれの利点と欠点について考察してください。- 3x3の行列を
std::array
を使って初期化し、その対角要素の合計を計算するプログラムを書いてください。
この章では、std::array
の基本的な使い方から応用までを学びました。これにより、安全で効率的な固定サイズ配列の扱い方を理解できたはずです。