具有不同顺序或变量的模板类(Color / Pixel类)

时间:2009-11-11 19:27:37

标签: c++ templates

我有两个类模板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;

3 个答案:

答案 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_listinherit_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];}
};