Pre*_*sor 6 c++ unions bit-fields
我正在尝试创建一个可变大小的颜色类 - 给定模板确定的值数组,我想为数组中的每个值创建命名别名,即:
template<int C = 3, typename T = unsigned char>
class Color {
public:
union {
T v[C];
struct {
T r, g, b, a;
};
};
};
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试为C = 3使用相同的类,则union要求4字节的大小('a'成员).或者,使用数学表达的位域大小((名为a,anonymous T成员的结构,大小在C> 3时评估为1),编译器发出一个允许警告(不可抑制,根据In gcc,如何静音 -敏感警告?),不适合大规模API的东西.
我如何允许单个类处理不同数量的变量,同时保留每个变量名称而不实现递归包含宏魔法(试过这个,不应该).提前致谢!
编辑:为了澄清问题,以下任何一个答案将解决此问题:
您可以针对 C 的不同情况对该结构进行专门化:
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;
};
};
Run Code Online (Sandbox Code Playgroud)
请注意,匿名结构是非标准的。
如果可以使用成员函数,我认为这将是更好的方法:
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_;
};
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
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";
}
Run Code Online (Sandbox Code Playgroud)