コンテナ
STLでは、ベクタ(std::vector)、スタック(std::stack)、キュー(std::queue、std::deque)、マップ(std::map)、セット(std::set)、双方向リスト(atd::list)などがすでに利用できたので、基本的なコンテナは整備されていたと言えます。C++ 11以降では、配列(std::array)、単方向リスト(std::forward_list)などが使えるようになりました。
配列std::array[C++11]
言語仕様としての配列があるから、コンテナとしての配列はいらないんじゃないかと思われますが、より簡便に安全に使えるものとして、std::arrayが使えるようになっています。
#include <array> …略… array<int, 5> x = {{0, 1, 2, 3, 4}}; auto y = array<int, 5>{{0, 1, 2, 3, 4}}; auto z = array<int, 5>{0, 1, 2, 3, 4}; // C++ 14以降
std::arrayを使うには、<array>ヘッダファイルをインクルードします。また、3つの文は同じ意味です。3番目(z)だけは、C++ 14以降で可能になった、内側の中カッコを省略できる記法です。
std::arrayの各要素へのアクセスは、配列と同じで大カッコ([])を使います。要素数を取得するには、size関数を使えます。C言語では、sizeof演算子を使っていましたね。なお、C++ 17以降はstd::size関数でも要素数を取得できます。
for(int i = 0; i < x.size(); i++) { // size(x)でもOK(C++ 17) cout << i << ":" << x[i] << endl; }
std::arrayでは、at関数を使うことで、添え字の範囲チェックを含めたアクセスも可能です。添え字が範囲外の場合は、std::out_of_range例外が発生します。
try { x.at(99) = 99; } catch (out_of_range& e) { cout << "out of range" << endl; }
at関数の戻り値は、指定する要素への参照です。std::arrayオブジェクトがconstである場合には、参照もconstとなります。
スパンstd::span[C++20]
できるだけ安全なコードが望まれる現在の流れを鑑みて、C++ 20には配列や生ポインタを安全に使うことのできるstd::spanが実装されました。std::spanにより、配列などの範囲外アクセスなどからガードされるようになるので、より安全なコードとできます。std::spanに与えることができるのは、配列、生ポインタ、std::vector、std::arrayなどです。
#include <span> …略… int a[] = {0, 1, 2}; span<int> si(a); cout << si.front() << "," << si.back() << endl; // 実行結果:0,2 cout << si[9] << endl; // 実行結果:0
std::spanを使うには、<array>ヘッダファイルをインクルードします。std::spanのインスタンスを生成するには、コンストラクタの引数にシーケンス(この場合は配列全体)を指定します。いったんstd::spanオブジェクトになると、front関数、back関数などにより配列の要素に安全にアクセスできるようになります。要素へのアクセスは[]演算子を使ってもできますが、範囲外の添え字を使うと、結果は未定義となります(この場合は0が返っている)。
std::spanにすることでイテレータなども使えるようになりますので、配列や生ポインタを使うケースがあれば、std::spanの利用を検討しましょう。