1. 導入: なぜ次元数の取得が必要なのか
C++でプログラミングをしていると、関数の引数として受け取った配列の「次元数」を知りたくなる場面があります。例えば、機械学習のデータ処理や画像解析など、多次元配列を扱う際、そのデータが何次元であるかによって処理を分岐させたいというケースです。
従来はテンプレートの特化などで複雑に記述する必要がありましたが、C++17から登場した std::rank_v を使えば、たった一行で、しかも非常に可読性の高いコードで次元数を取得できるようになりました。
2. 基礎知識: std::rank_vとは?
std::rank_v は、C++17で導入された「型特性(Type Traits)」の一つです。簡単に言うと、「コンパイル時に、指定した型の配列の次元数を計算して整数として返してくれるツール」です。
本来、C++の配列は単なるメモリの塊であり、配列自体が自分の次元数を知っているわけではありません。しかし、コンパイル時にその型情報(int[2][3]など)を解析することで、コンパイラは次元数を特定できます。この仕組みを簡単に利用できるようにしたのが std::rank_v です。
3. 実装/解決策: 基本的な使い方
使い方は非常にシンプルです。ヘッダーファイル
戻り値は std::size_t 型(符号なし整数)となります。
4. サンプルプログラム
以下のコードをコピーして、お手元の環境でコンパイルしてみてください。配列の定義に応じて、正しく次元数が取得されていることが確認できます。
include <iostream>
include <type_traits>
int main() {
// 1次元配列の次元数(結果: 1)
constexpr size_t dim1 = std::rank_v<int[10]>;
// 2次元配列の次元数(結果: 2)
constexpr size_t dim2 = std::rank_v<int[2][3]>;
// 3次元配列の次元数(結果: 3)
constexpr size_t dim3 = std::rank_v<int[5][4][3]>;
std::cout << "1次元配列の次元数: " << dim1 << std::endl;
std::cout << "2次元配列の次元数: " << dim2 << std::endl;
std::cout << "3次元配列の次元数: " << dim3 << std::endl;
return 0;
}
5. 応用・注意点
現場で使う際に知っておくべき注意点が2つあります。
注意点1: 配列以外の型には使えない
std::rank_v はあくまで「配列型」に対して使うものです。もし int や float といった単一の型に対して使用すると、次元数は「0」と評価されます。これはエラーではなく仕様ですが、意図しない挙動にならないよう注意が必要です。
注意点2: ポインタとの違いに注意
初心者の方がよく混同するのが「配列」と「ポインタ」です。例えば int ptr; と宣言されたポインタに対して std::rank_v を使っても、配列ではないため次元数は「0」になります。あくまで「静的にサイズが決まっている配列型」に対してのみ有効であることを覚えておきましょう。
このツールを活用することで、テンプレートメタプログラミングの第一歩を軽やかに踏み出してみてください!

コメント