You can do structure specialization for different C cases:
template <int C = 3, typename T = unsigned char> union Color; template <typename T> union Color<3,T> { T v[3]; struct { T r,g,b; }; }; template <typename T> union Color<4,T> { T v[4]; struct { T r,g,b,a; }; };
Please note that anonymous structures are non-standard.
If using member functions is an option, I think that would be a better way:
template <int C,typename T> class Color { public: using Values = T[C]; Values &v() { return v_; } const Values &v() const { return v_; } T& r() { return v_[0]; } T& g() { return v_[1]; } T& b() { return v_[2]; } template <int C2 = C, typename = typename std::enable_if<(C2>3)>::type> T& a() { return v_[3]; } const T& r() const { return v_[0]; } const T& g() const { return v_[1]; } const T& b() const { return v_[2]; } template <int C2 = C, typename = typename std::enable_if<(C2>3)>::type> const T& a() const { return v_[3]; } private: Values v_; };
Then you can use it as follows:
int main() { Color<3,int> c3; Color<4,int> c4; c3.v()[0] = 1; c3.v()[1] = 2; c3.v()[2] = 3; std::cout << c3.r() << "," << c3.g() <<"," << c3.b() << "\n"; c4.v()[0] = 1; c4.v()[1] = 2; c4.v()[2] = 3; c4.v()[3] = 4; std::cout << c4.r() << "," << c4.g() << "," << c4.b() << "," << c4.a() << "\n"; }
source share