#はじめに
例としてD言語ではalias
を使うことで変数等に別名をつけれます。
struct Float4
{
float x,y,z,w;
alias r=x,g=y,b=z,a=w;
};
この場合、Float4
型に対して、xyzwで扱うだけでなくrbgaでのアクセスも可能になります。(HLSLのfloat4
のようなイメージ)
同じようなことをC++でやるにはどうすればよいか考えてみます。
#方法1:define
#define r x
#define g y
#define b z
#define a w
struct Float4
{
float x,y,z,w;
};
こんなコードを書く人は島流しの刑にすべきです。
やめてください。
論外。
#方法2: 参照
struct Float4
{
float x,y,z,w;
float& r=x, g=y, b=z, a=w;
Float4() = default;
Float4(const Float4& other):
x(other.x),
y(other.y),
z(other.z),
w(other.w),
r(x),
g(y),
b(z),
a(w)
{}
Float4& operator =(const Float4& other)
{
this->x = other.x;
this->y = other.y;
this->z = other.z;
this->w = other.w;
return *this;
}
};
メンバに参照型を持てば似たようなことができるかもしません。
しかし、参照型の分メモリサイズが増えてしまうことや、ただしくコピーコンストラクタをかかないとディープコピーできない等の問題があります。
あんまりオススメはできない。
#方法3:共用体
struct Float4
{
union
{
struct
{
float x, y, z, w;
};
struct
{
float r, g, b, a;
};
};
};
共用体と無名構造体を利用してxyzwとrbgaでメモリ領域を共有する方法。
状況次第ではメモリサイズのこととか意識しないといけないかもですが、それなりにオススメできそう?
#方法4:プロパティ
もしVisual Studioを使っているならプロパティを利用するのもありかもしれません
#define PropertyAlias(base,name,...)\
__declspec(property(get = get_##base, put = set_##base)) __VA_ARGS__ name;\
__VA_ARGS__ & get_##base(){return base;}\
void set_##base(const __VA_ARGS__& value){base = value;}
struct Float4
{
float x, y, z, w;
//書くのがめんどくせえのでとりあえずマクロで許して
PropertyAlias(x, r, float)
PropertyAlias(y, g, float)
PropertyAlias(z, b, float)
PropertyAlias(w, a, float)
};
個人的に書くのがめんどくさいです。
VSのプロパティの詳しい説明はこちら
#まとめ
今回は思いついた4つの方法を紹介しましたが他にもいい方法があったら教えてください。
そもそも、こんな事がしたい状況にそんなにならないとは思いますが…?