2009-11-11 5 views
2

я получил два шаблона класса Color3_t и Color4_t, хранящие 3 и 4 цветовых каналы и выглядит следующим образом:Шаблон класса с другим порядком или переменными (цвет/классом Pixel)

template <typename TYPE> 
struct Color3_t 
{ 
    TYPE Red; 
    TYPE Green; 
    TYPE Blue; 

    void Zero() 
    { 
     Red = Green = Blue = 0; 
    } 
    (...) 
} 

Оба шаблона имеет несколько функций для переворачивания , обмениваясь и т. д. цветовых каналов, и у меня есть еще один специализированный шаблон, который наследует эти классы - в случае, если TYPE является половинным float или float вместо целого.

Проблема в том, что порядок цветовых каналов: красный, зеленый и синий в настоящее время исправлен - это означает, что мне нужно будет создать версию шаблона класса Color3_t для каждого другого порядка цветовых каналов (например, BGR, GRB и т. Д. .). Как можно обеспечить и аргумент с другим цветовым порядком - скорее всего, это указывает на структуру цвета, как показано ниже.

структуры Цвет данных для 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; 
+2

Когда будет выполняться заказ членов? –

+0

Также. Зачем нужен порядок? – ChadNC

+0

Для доступа к этим объектам (структурам) в массивах или буферах памяти - после загрузки необработанных данных из файла - для доступа к ним по именам, а не прямым индексам 0,1,2. Я также получил класс изображения, который работает в разных цветовых/пиксельных форматах, а использование имен каналов вместо цифр просто намного проще. Различные форматы файлов используют другой порядок, например, изображения BMP используют RGB, TGA используют BGR, не говоря уже о том, что упростить извлечение 4-х канальных значений цвета из ULONG/DWORD. – mslaf

ответ

1

вам нужно нажать на тип, который хранится на красный/зеленый/синий вниз в цвете *** _ т классы как так:

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 просто взять один шаблонный параметр, который является одним из вашего цвета *** _ типы т:

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.

+0

Похоже, это то, что я имел в виду, но не смог найти правильный синтаксис, чтобы выразить это;) Спасибо. – mslaf

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];} 
}; 
+0

«Я предполагаю, что вы не можете делать то, что хотите, во время компиляции с помощью шаблонов». Вы могли бы принять вашу идею и поместить эти функции в класс признаков. Но остается вопрос: почему вопрос о порядке? – sbi

+0

Спасибо, но это то, что у меня уже было. Что касается времени компиляции, я бы хотел, чтобы шаблоны были проще в обслуживании - значит, короче, но не для стоимости сложного кода, использующего эти шаблоны. – mslaf

+0

Причина разного порядка объясняется выше;) – mslaf

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> 
{}; 

Я не пытался скомпилировать ни одно из этого, так что это будет неловко ошибки. Я уже краснею.

+0

Я думаю, что решение Бретта выше немного проще. Спасибо. – mslaf

+0

Это _is_ сложно, если у вас нет 'type_list' и' inherit_from' в вашем ящике инструментов. У меня их, поэтому мне нужно всего лишь несколько строк в первом фрагменте кода. ':)' – sbi