我有两个类模板Color3_t和Color4_t,它们存储3个和4个颜色通道,如下所示:
template <typename TYPE>
struct Color3_t
{
TYPE Red;
TYPE Green;
TYPE Blue;
void Zero()
{
Red = Green = Blue = 0;
}
(...)
}
两个模板都有几个用于反转,交换等颜色通道的功能,我有另一个继承这些类的专用模板 - 如果TYPE是半浮点数或浮点数而不是整数。
问题是颜色通道的顺序:红色,绿色和蓝色目前是固定的 - 这意味着我必须为每个其他颜色通道顺序(如BGR,GRB等)创建Color3_t类模板的版本。 )。如何提供和论证不同的颜色顺序 - 最有可能指向下面的颜色结构。
RGB和BGR颜色顺序的颜色数据结构:
template <typename TYPE>
struct ColorRGB_t
{
TYPE Red;
TYPE Green;
TYPE Blue;
};
template <typename TYPE>
struct ColorBGR_t
{
TYPE Blue;
TYPE Green;
TYPE Red;
};
和我想要的东西 - 这显然是错误的和不正确的,但应该让我知道我想要实现的目标。
template <typename TYPE, class COLORORDER<TYPE>>
struct Color3_t : public COLORORDER<TYPE>
{
void Zero()
{
Red = Green = Blue = 0;
}
(...)
};
我也想直接访问每个颜色通道:
typedef Color3_t<BYTE,ColorBGR_t<BYTE>> ColorRGB8bpc;
ColorRGB8bpc oColor;
oColor.Red = 0;
而不是:
oColor.SomoObject.Red = 0;
答案 0 :(得分:1)
你需要将为红色/绿色/蓝色存储的类型向下推入Color *** _ t类,如下所示:
template <typename TYPE>
struct ColorRGB_t
{
typedef TYPE value_type;
value_type Red;
value_type Green;
value_type Blue;
};
template <typename TYPE>
struct ColorBGR_t
{
typedef TYPE value_type;
value_type Blue;
value_type Green;
value_type Red;
};
然后Color3只使用一个模板参数,它是您的Color *** _ t类型之一:
template <typename Order_t>
struct Color3 : public Order_t
{
typedef typename Order_t::value_type value_type;
void Zero()
{
//static cast zero here to avoid compiler warnings when value_type is a float or double
Order_t::Red = Order_t::Green = Order_t::Blue = static_cast<value_type>(0);
}
};
并将对象声明为:
Color3<ColorBGR_t<float> > c1;
Color3<ColorRGB_t<float> > c2;
这对你有用吗?它避免了在运行时索引到数组的开销,而Red / Green / Blue成员可以像c1.Red = 0.0
一样直接使用。
答案 1 :(得分:1)
我的代码基于这样的想法:基本的非虚拟类按照它们被声明的顺序布置在内存中。我认为这不是保证,但IMO至少相当普遍。它还允许您将颜色类型用于不同数量的颜色。
template <typename TYPE> struct R { TYPE Red; };
template <typename TYPE> struct G { TYPE Green; };
template <typename TYPE> struct B { TYPE Blue; };
template <typename Bases>
struct Color : inherit_from<Bases>
{
// ...
};
typedef Color< generate_color_list<R,G,B>::result_t > ColorRGB_t;
typedef Color< generate_color_list<B,G,R>::result_t > ColorBGR_t;
现在您所需要的只是generate_color_list
和inherit_from
。
给出这个简单的类型列表定义
struct nil {};
template< typename Head, typename Tail >
struct type_list {
typedef Head head_type;
typedef Tail tail_type;
};
这是对颜色类型列表生成器的一种不太普遍的尝试:
template< typename T1, typename T2, typename T3 >
struct generate_color_list {
typedef type_list< T1,
type_list< T2,
type_list< T3, nil > > > result_t;
};
这是inherit_from
:
template< typename List >
struct inherit_from;
template<>
struct inherit_from<nil> {}
template< typename Head, class Tail >
struct inherit_from< type_list<Head,Tail> >
: public Head
, public inherit_from<Tail>
{};
我没有尝试编译任何此类内容,因此会出现令人尴尬的错误。我已经脸红了。
答案 2 :(得分:0)
我猜你在编译时不能用模板做你想做的事。你可能有 在运行时这样做。
要获得您想要的效果,您需要执行以下操作:
template < typename TYPE >
struct color3channel
{
TYPE channels[3];
int rIndex, bIndex, gIndex;
TYPE getR() const {return channels[rIndex];}
TYPE getG() const {return channels[gIndex];}
TYPE getB() const {return channels[bIndex];}
};