配列の要素に名前をつける
C/C++ で配列の各要素に名前をつける方法について.例えば,
unsigned char col[4];
として宣言された col の各要素を red, green, blue, alpha のような識別子でも参照できるようにする.
方法は簡単で,共用体 union を無名で使う.例えば,
struct TPoint3D { union { struct {double x,y,z;}; double p[3]; }; };
このような構造体 TPoint3D を作ったとき,この構造体のサイズは sizeof(TPoint3D)=24 だ(sizeof(double)=8 の場合).ここで共用体の性質から, x と p[0], y と p[1], z と p[2] はそれぞれ同じメモリアドレスに割り当てられているので, p[1] に識別子 x で参照することも可能である.
サンプルプログラムをもとに,もう少し解説する:
#include <iostream> struct TPoint3D { union { struct {double x,y,z;}; double p[3]; }; TPoint3D(void) : x(0.0), y(0.0), z(0.0) {}; TPoint3D(const TPoint3D &v) : x(v.x), y(v.y), z(v.z) {}; TPoint3D(const double &_x, const double &_y, const double &_z) : x(_x), y(_y), z(_z) {}; double& operator[](int i) {return p[i];}; const double& operator[](int i) const {return p[i];}; }; std::ostream& operator<< (std::ostream &os, const TPoint3D &p) { const char *delim[]={", ",", ",")"}; os<< "("; for(int i(0); i<3; ++i) os<< p[i]<< delim[i]; return os; } using namespace std; int main(int argc, char**argv) { TPoint3D p (1.0, 2.0, 3.0); cout<< "sizeof(double)= "<< sizeof(double)<< endl; cout<< "sizeof(TPoint3D)= "<< sizeof(TPoint3D)<< endl; cout<< "p= "<< p<< endl; p.y= 5.0; cout<< "p.y= "<< p.y<< endl; p.z= -2.5; cout<< "p= "<< p<< endl; return 0; }
ここで TPoint3D の各要素は, main 関数の中でやっているように, p.y や p.z のようにして参照できる.一方, operator<< のように, p[i] (これは p.p[i] と等価だが, operator[] をオーバーロードし,短縮している)のようにして参照することもできる.
このように無名共用体を使えば,配列の各要素に個別に名前を付けられる. x, y, z とか red, green, blue, alpha のように個別の名前で参照した方が分かりやすいが, for ループなどで一気にアクセスもしたい,という場合に使える小技だ.配列サイズが小さい場合にしか使えないが,そもそも配列サイズが大きくなれば,個別に名前を付けようとは思わないだろう.