Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Шаблоны - и union 
:(
    Опции темы
Lazin
Дата 27.12.2007, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Я сейчас работаю над одной проблемой, которая вызывает некоторые затруднения, вот ее упрощенный аналог:
есть такая структура 
Код

struct VALUE
{
 union {
  double dbl;
  long i64;
 };
 byte type;
};
 это вариантный тип данных, что-бы узнать что она содержит нужно проверить поле type
.
она должна обрабатываться методом
Код

template<Format, Packer>
void Pack(VALUE & v)
{
 Format::Process(v);
 Packer::Pack(v);
}


шаблонные параметры: Format - преобразует число содержащееся в структуре по некоторому правилу, реализации Format исходят из того что в структуре содержится число определенного типа (поле type не проверяется)
Код

class DoubleFormat1
{
public:
  static void Process(VALUE& v)
  { сделать что то с v.dbl %)
  }
};


Код

class IntFormat1
{
public:
  static void Process(VALUE& v)
  { сделать что то с v.i64
  }
};


в общем эти классы нужны для преобразования значения VALUE? и их может быть много

Packer - класс обеспечивающий сжатие данных, он то-же работает с VALUE как со значением определенного типа (предварительно структура должна быть обработана соответствующим методом Format)
Код

class IntPacker1
{
public:
  static void Pack(VALUE& v)
  { сделать что то с v.i64 
  }
};


в общем я этим хочу добится 2х вещей, что-бы не проверять каждый раз тип структуры VALUE, так как он известен на этапе компиляции, и комбинировать разные методы обработки VALUE
короче я хочу делать так:
Код

Pack<IntFormat1, IntPacker1>(v);
Pack<IntFormat2, IntPacker3>(v);
Pack<DoubleFormat4, DoublePacker1>(v);

.....
проблема в том что теперь возможен и такой вариант
Код

Pack<IntFormat1, DoublePacker1>(v);

и тд
что в моем случае недопустимо
можно в принципе использовать STATIC_ASSERT что-бы на стадии компиляции запрещать невозможные комбинации, но я не могу отделаться от одной мысли: 
если у меня возникла такая ситуация, значит декомпозиция задачи выполнена не верно, я где-то допустил ошибку в проектировании, что вы думаете по этому поводу?
PM MAIL Skype GTalk   Вверх
archimed7592
Дата 27.12.2007, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Код

struct ToDouble
    :    public std::unary_function< VALUE &, double & >
{
    double &operator()(VALUE &x) const
    { return x.dbl; }
};
struct ToI64
    :    public std::unary_function< VALUE &, long & >
{
    long &operator()(VALUE &x) const
    { return x.i64; }
};

template<Converter, Format, Packer>
void Pack(VALUE & v)
{
 Converter c;
 Converter::result_type r = c(v);
 Format::Process(r);
 Packer::Pack(r);
}

Fromatter и Packer соответственно переделать под более строгие типы(double и long).


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Lazin
Дата 28.12.2007, 09:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



archimed7592, твой вариант:
+ делает невозможным лишние комбинации
- лишний шаблонный параметр
-----------------------------
мне кажется что можно сделать проще, но как - пока не скажу))
PM MAIL Skype GTalk   Вверх
archimed7592
Дата 28.12.2007, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(Lazin @  28.12.2007,  09:26 Найти цитируемый пост)
мне кажется что можно сделать проще, но как - пока не скажу)) 

Можно: добавить к VALUE неявное преобразование как к double, так и к long, после чего форматеры и пакеры писать так, чтобы принимали аргумент нужного типа(а не VALUE).
Только, лично мне кажется наоборот, что с третьим параметром кошернее smile.

Добавлено через 1 минуту и 1 секунду
Ещё можно сделать так, чтобы этот третий параметр шёл аргументом и вычислять его автоматически - тогда и параметр будет и указывать его не нужно будет smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
baldina
Дата 28.12.2007, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



archimed7592,
Цитата

с третьим параметром кошернее 

в принципе - да, но лучше его неявно использовать, учтя, что он есть свойство Format и Packer: сделаем его параметром этих классов

Lazin, посмотри:
Код

template <typename T> 
struct PackTraits {
  // нет преобразования PackTraits<double> <-> PackTraits<int>
};

template <typename T> struct Format {
  typedef PackTraits<T> type_traits;
};

template <typename T> struct Packer {
  typedef PackTraits<T> type_traits;
};

template <typename F, typename P> 
class Pack {
  // не должно компилиться если F и P параметризованы разными типами
  void _check_type_traits (const typename F::type_traits& f=F::type_traits()) { typename P::type_traits p(f); } 
public:
  Pack () { _check_type_traits(); }
};

class IntFormat2 : public Format<int> {};
class IntPacker3 : public Packer<int> {};
class DoubleFormat4 : public Format<double> {};
class DoublePacker1 : public Packer<double> {};

Pack<IntFormat2, IntPacker3> v;
Pack<DoubleFormat4, DoublePacker1> v1;
Pack<IntFormat2, DoublePacker1> v2; // error


Добавлено @ 18:54
можно даже так, что бы в конструкторах Pack не думать о проверках:
Код

template <typename F, typename P> 
struct Pack_Helper {
  Pack_Helper () { typename P::type_traits (typename F::type_traits()); }
};

template <typename F, typename P> 
class Pack : public Pack_Helper <F,P> {
};


Это сообщение отредактировал(а) baldina - 28.12.2007, 19:09
PM MAIL   Вверх
baldina
Дата 28.12.2007, 19:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101



Lazin,
Цитата

но я не могу отделаться от одной мысли

имхо все у тебя с дизайном правильно, просто чуть не дотянул до реализации
 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0763 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.