Re[3]: Шаблон для работы с массивом разных типов
От: alexanderfedin США http://alexander-fedin.pixels.com/
Дата: 29.10.03 08:05
Оценка:
Здравствуйте, glut, Вы писали:

>>т.е. обойтись совсем без базового класса (тот, который оперирует PBYTE)?

>>Тогда будет 15 классов (типов же 15), мне это не нравится =((

а у тебя настолько разные типы, с которыми нужно оперировать?
_Traits — это класс настройки на конкретные особенности типа, то есть здесь
он определяет операции по копированию и сравнению экземпляров.
В общем случае это будет
template <typename _Ty>
struct _DefaultTraits
{
    static void copy(_Ty *dst, const _Ty &src)
    {
        *dst = src;
    }

    static bool compare(const _Ty &lhs, const _Ty &rhs)
    {
        return (lhs == rhs);
    }
};

Для примитивных типов операции копирования и сравнения определены языком.
Для типа массива напиши что-то типа:
template <typename _Ty>
struct _ArrayTraits
{
    static void copy(_Ty *dst, const _Ty &src)
    {
        for (int i = 0; i < sizeof(src)/sizeof(src[0]); ++i) (*dst)[i] =
src[i];
    }

    static bool compare(const _Ty &lhs, const _Ty &rhs)
    {
        for (int i = 0; i < _size; ++i)
            if (!(dst[i] == src[i])) return false;
        return true;
    }
};

для своих типов определи операции сравнения и присвоения:
class MyClass
{
   public:
        MyClass &operator=(const MyClass &src) {...}
        friend bool operator==(const MyClass &lhs, const MyClass &rhs) {...}
};

используй так:
template <typename _Ty, typename _Traits = _DefaultTraits>
class CArrayClass
{
    friend class _Traits;

    static void copy(_Ty *dst, const _Ty &src)
    {
        _Traits::copy(dst, src);
    }

    static bool compare(const _Ty &lhs, const _Ty &rhs)
    {
        return _Traits::compare(lhs, rhs);
    }
};

typedef char STR255[255];
typedef struct {
    DWORD l, r, b, d;
} RECT;
bool operator==(const RECT &lhs, const RECT &lhs) { return (lhs.l == rhs.l
&& lhs.r == rhs.r && lhs.b == rhs.b && lhs.d == rhs.d); }
typedef unsigned int UINT;

void main()
{
    typedef CArrayClass<STR255, _ArrayTraits<STR255> >  _ArrayUtilitySTR255;
    typedef CArrayClass<RECT, _DefaultTraits>  _ArrayUtilityRECT;
    typedef CArrayClass<UINT, _DefaultTraits>  _ArrayUtilityUINT;

    STR255 s1 = "hghghjjhg", s2 = "aaaaaa";
    if (!_ArrayUtilitySTR255::compare(s1, s2))
        _ArrayUtilitySTR255::copy(s1, s2);

    RECT r1 = {0, 1, 2, 3}, r2 = {3, 4, 5, 6};
    if (!_ArrayUtilityRECT::compare(r1, r2))
        _ArrayUtilityRECT::copy(r1, r2);

    UINT ui1 = 0, ui2 = 2;
    if (!_ArrayUtilityUINT::compare(ui1, ui2))
        _ArrayUtilityUINT::copy(ui1, ui2);
}


если тебе нужна независимость класса CArrayClass от обрабатываемых типов,
тогда примени метафункции — будешь по-прежнему обходиться без накладных
расходов на вызов виртуальных функций, что с поддержкой компилятором inline
подстановки даст тебе быстродействие прямого использования необходимых
алгоритмов для соотвествующих типов.

С уважением,
Александр Федин (AlexanderFedin@iname.com)
Respectfully,
Alexander Fedin.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.