導入
C++でプログラミングをしていると、配列やコンテナの要素数を取得したい場面は非常に多くあります。これまでは、組み込み配列に対してはsizeof演算子を使い、std::vectorなどのコンテナには.size()メンバ関数を使う、といったように「対象によって書き方を変える」必要がありました。C++17から導入されたstd::size()を使うことで、これらを統一的なインターフェースで扱えるようになり、コードの可読性向上と不整合によるバグの防止が可能になります。
基礎知識
std::size()は、
これまでのC++では、生の配列(int arr[]など)に対しては、sizeof(arr) / sizeof(arr[0])という少し冗長でミスを誘発しやすい書き方をするのが一般的でした。一方、std::vectorなどは.size()というメンバ関数を持っています。std::size()は、引数として渡されたものがコンテナであればそのメンバ関数を呼び出し、配列であれば型推論によってその長さを正しく返すという、非常に賢い関数です。
実装/解決策
使い方は非常にシンプルです。引数に調べたい配列やコンテナを渡すだけです。戻り値はstd::size_t型となります。これにより、テンプレート関数を作成する際など、引数が配列なのかコンテナなのかを意識せずに要素数を取得できるため、ジェネリックなプログラミングが劇的に書きやすくなります。
サンプルプログラム
以下のコードは、生の配列とstd::vectorの両方に対してstd::size()を使用する例です。
include
include
include
int main() { std::size()を使用する際の注意点は、必ずC++17以降のコンパイラ環境が必要であるという点です。また、あくまで「その型がサイズ情報を取得できるインターフェースを持っていること」が前提となります。もし、自作クラスなどでこの関数に対応させたい場合は、メンバ関数としてsize()を実装しておくか、std::sizeをオーバーロードすることで対応可能です。 また、ポインタ(int p = arr;)に対してstd::size()を使用しようとすると、コンパイルエラーになります。これは配列のサイズ情報が失われているためであり、言語仕様として非常に安全な設計と言えます。配列のサイズを正しく知りたい場合は、必ず配列の寿命が生きているスコープ内で使用するようにしてください。
// 1. 生の配列での使用例
int arr[] = {10, 20, 30, 40, 50};
// 従来の sizeof(arr)/sizeof(arr[0]) よりも安全で簡潔です
std::size_t arr_size = std::size(arr);
std::cout << "配列の要素数: " << arr_size << std::endl;
// 2. std::vectorでの使用例
std::vector
// コンテナに対しても同じ std::size() を使えます
std::size_t vec_size = std::size(vec);
std::cout << "ベクトルの要素数: " << vec_size << std::endl;
return 0;
}
応用・注意点

コメント