目次
はじめに
C++でvectorなどのコンテナを扱う際、そのコンテナに現在いくつの要素が格納されているかを知ることは、ループ処理やメモリ管理の基本となります。この「要素数」を取得するために、C++にはいくつかの方法が用意されています。
この記事では、要素数を取得するための3つの主要な方法と、それぞれの特徴・使い分けについて解説します。
.size()メンバ関数: 最も基本的な方法。std::size()(C++17): C言語スタイルの配列にも使える、より汎用的な方法。std::ssize()(C++20): 符号付き整数でサイズを返す、より安全な方法。
要素数を取得するサンプルコード
このコードは、vectorとC言語スタイルの配列の両方に対して、3つの異なる方法で要素数を取得し、その結果を出力します。
完成コード
#include <iostream>
#include <vector>
#include <iterator> // std::size, std::ssize
using namespace std;
int main() {
vector<string> items = {"りんご", "みかん", "ぶどう"};
int c_style_array[] = {10, 20, 30, 40};
// --- 1. .size() メンバ関数 ---
// vectorなどのコンテナクラスが持つ
cout << "1. .size()メンバ関数 (vector): " << items.size() << endl;
// --- 2. std::size() フリー関数 (C++17) ---
// コンテナとC言語スタイル配列の両方に使える
cout << "2. std::size() (vector): " << size(items) << endl;
cout << "2. std::size() (C配列): " << size(c_style_array) << endl;
// --- 3. std::ssize() フリー関数 (C++20) ---
// 符号付き整数でサイズを返す
cout << "3. std::ssize() (vector): " << ssize(items) << endl;
// ssize()の利点: 符号なし整数との比較による警告を回避
vector<int> empty_vec;
// ssize(empty_vec) - 1 は -1 になるが、empty_vec.size() - 1 は非常に大きな正の数になる
if (ssize(empty_vec) > 0) {
cout << "ssize()を使った安全なループ" << endl;
}
return 0;
}
各方法の解説
1. .size() メンバ関数
- 使い方:
コンテナ変数.size() - 特徴:
std::vectorやstd::stringなど、ほとんどの標準ライブラリコンテナが持つ、最も基本的なメンバ関数です。 - 戻り値: 符号なし整数型 (
size_type) で要素数を返します。 - 注意点: C言語スタイルの配列(例:
int arr[5];)には使えません。
2. std::size() フリー関数 (C++17)
- 使い方:
size(コンテナ変数) - 特徴: C++17で導入されました。コンテナのメンバ関数
.size()を呼び出すだけでなく、C言語スタイルの配列の要素数も自動で計算してくれます。より汎用的な書き方ができます。 - 戻り値:
.size()と同じく、符号なし整数型です。
3. std::ssize() フリー関数 (C++20)
- 使い方:
ssize(コンテナ変数) - 特徴: C++20で導入されました。
std::sizeと同様に汎用的ですが、戻り値の型が異なります。 - 戻り値: 符号付き整数型 (
signed) で要素数を返します。
ssize() を使う最大のメリット
size() や .size() が返す符号なし整数は、0 から値を引くと、マイナスにならずに非常に大きな正の数になってしまう(オーバーフローする)という特性があります。
vector<int> v; // 空のvector
// v.size() は 0 (unsigned)
// v.size() - 1 は 0 - 1 ではなく、非常に大きな数になる
for (int i = 0; i < v.size() - 1; ++i) { // ループが意図せず実行される危険性
// ...
}
ssize() を使うと、ssize(v) - 1 は正しく -1 になるため、このような意図しないバグを防ぐことができ、より安全なコードになります。
まとめ
今回は、C++でコンテナの要素数を取得する3つの方法を解説しました。
| 方法 | 対応コンテナ | 戻り値の型 | 推奨度 |
.size() | 標準コンテナ | 符号なし | ◯ (基本) |
std::size() | 標準コンテナ, C配列 | 符号なし | ◯ (C++17) |
std::ssize() | 標準コンテナ, C配列 | 符号付き | ◎ (C++20, 最も安全) |
結論として、C++20以降の環境であれば、符号なし整数にまつわるバグを避けるために、std::ssize() を使うのが最も安全で推奨される方法です。
