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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Динамическое получение типа 
V
    Опции темы
boostcoder
Дата 21.10.2012, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 49
Всего: 110



вот представь, что есть функция которую предложил Dem_max. в этой функции наверняка происходит не просто вывод значения, а наверняка, это значение еще как-то используется. т.е. эта функция - реализация чего-то.
в один прекрасный день, ты решил добавить в твою систему кастов, новый тип. ты 1)декларишь енум, 2)лезешь изменять реализацию. против первого я ничего не имею против потому, что декларации/тайпдефы/форварды - это все свойственно плюсам потому, что на основании деклараций компилятор производит специализации одного и того же кода, за тебя.
и представь switch, в который ты лезешь и начинаешь добавлять новый case с оглядкой на то, чтоб случайно его не продублировать и на то, чтоб присвоить ему корректное значение. и это хорошо что с++ статически типизируемый, ошибки ты получишь на стадии компиляции. основные два аргумента: 1)ты не будешь каждый раз при добавлении нового case, писать его секцию руками - ты ее скопипастишь. 2)эта функция может находится где-то в дебрях проекта, в которые никто уже годы не лез. а если проект состоит из подпроектов, и эта функция реализована в одном из подпроектов, то тебе придется пересобирать подпроект, ведь предложенная функция не шаблонная.

а теперь сравни с тем, как все описанное будет происходить при использовании моего примера. комментарии, полагаю, излишни.

PM WWW   Вверх
volatile
Дата 21.10.2012, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 37
Всего: 85



Цитата(W4FhLF @  21.10.2012,  20:46 Найти цитируемый пост)
Может кто-нибудь не поленится и объяснит? 

Скажу короко - есть задачи где это нужно.
(ну хотя бы потому, что свитч занимает процессорное время. Решение-же бусткодера, выполняется в момент компиляции.
в реал-тайме там просто ничего не делается. Есть и другие случаи, где это просто необходимо.


PM MAIL   Вверх
W4FhLF
Дата 21.10.2012, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(volatile @  21.10.2012,  21:08 Найти цитируемый пост)
(ну хотя бы потому, что свитч занимает процессорное время. Решение-же бусткодера, выполняется в момент компиляции.


До тех пор пока эта функция не вызывается в цикле миллионы раз -- это чистой воды premature optimization. switch достаточно легковесно реализуется на уровне инструкций. 

Но в некоторых задачах это действительно может быть необходимо.


Цитата(boostcoder @  21.10.2012,  21:05 Найти цитируемый пост)
1)ты не будешь каждый раз при добавлении нового case, писать его секцию руками - ты ее скопипастишь. 2)эта функция может находится где-то в дебрях проекта, в которые никто уже годы не лез. а если проект состоит из подпроектов, и эта функция реализована в одном из подпроектов, то тебе придется пересобирать подпроект, ведь предложенная функция не шаблонная.


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

Пускай автор решает, соответственно его задаче, которую мы не знаем.

Это сообщение отредактировал(а) W4FhLF - 21.10.2012, 21:18


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 21.10.2012, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 49
Всего: 110



Цитата(W4FhLF @  21.10.2012,  21:17 Найти цитируемый пост)
И писать реализацию для нового типа ты тоже скорее всего будешь копипастом и тоже, скорее всего, в том файле, где у тебя лежат реализации других типов. Не считаю это за аргументы.

я не буду писать реализацию. функция-то шаблонная.

PM WWW   Вверх
volatile
Дата 21.10.2012, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 37
Всего: 85



Цитата(borisbn @  21.10.2012,  14:12 Найти цитируемый пост)
Динамическое получение типа

Вообще, имхо, в чистом виде нельзя. Язык со статической типизацией, этим все сказано.

Если tag известен на момент компиляции, то foo нужно делать шаблонной.
Что и предложил бусткодер.  

Если же tag неизвестен на момент компиляции (а это собственно и есть динамический тип в чистом виде.), то остается только свитч.

напр:
Код

void foo (void * p)
{
    int tag;    
    std::cin >> tag; // можете сюда подставить любой другой способ получения tag
                     // неизвестный на момент компиляции
    
    // A.) здесь только свитч
    // 
    switch (tag)
    {
       case e1 :
        int value = *( (int*)p );
        cout << value;
        break;

       case e2 :
        short value = *( (short*)p );
        cout << value;
        ...
        // ну и т.д
    }
}


Eстественно свитч может быть замаскирован под какой-нибудь другой набор операторов.
факт остается фактом. В точке A, невозможно просто написать тип вроде такого:
typedef tag_2_type<tag>::type tag_t;
tag_t value = *( (tag_t*)p );

все вышесказанное, конечно-же имхо.
PM MAIL   Вверх
W4FhLF
Дата 21.10.2012, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 20
Всего: 121



Цитата(boostcoder @  21.10.2012,  21:20 Найти цитируемый пост)
я не буду писать реализацию. функция-то шаблонная.


Ок, если автору нужна простая шаблонная функция странно, что он её сразу не написал. 

volatile правильно заметил, что там, где речь заходит о динамической типизации всё сводится к пресловутому switch рано или поздно.


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
boostcoder
Дата 21.10.2012, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 49
Всего: 110



Цитата(W4FhLF @  21.10.2012,  21:43 Найти цитируемый пост)
Ок, если автору нужна простая шаблонная функция странно, что он её сразу не написал. 

я единственный кто читал топик и код ТС`а ?

Цитата(W4FhLF @  21.10.2012,  21:43 Найти цитируемый пост)
там, где речь заходит о динамической типизации всё сводится к пресловутому switch рано или поздно.

ниразу.
то, что пытается реализовать ТС - не динамическая типизация.
и то что пытается реализовать ТС, запросто реализуется более безопасными, расширяемыми и гибкими способами. и никакого switch.


Это сообщение отредактировал(а) boostcoder - 21.10.2012, 21:56
PM WWW   Вверх
volatile
Дата 22.10.2012, 02:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 37
Всего: 85



Цитата(boostcoder @  21.10.2012,  21:49 Найти цитируемый пост)
я единственный кто читал топик и код ТС`а ?

Нет не единственный.
Там на самом деле не ясно, что известно на момент компиляции, а что нет. приходиться догадываться.

Если судить чисто по примеру то там вообще сам тип известен, и прямолинейное решение лежит на поверхности.
Код

template <typename T>
void foo( T * p )
{
    T value = *p;
    cout << value;
}
 smile 
Но ясно что borisbn, не стал бы такие дурацкие вопросы задавать. и на основе этого, уже делаем дальнейшие предположения.
Тип, понятно что неизвестен. А известен какой-то тег (код типа), в соответствии с которым нужно восстановить тип.
Но насколько хорошо известен этот тег - неясно.

Вариант 1.
Есть некий тег (код типа), известный на момент компиляции.
В этом случае можно решать разными путями. Я бы безусловно выбрал темплейтный вариант. а ля boostcoder.
(это отнюдь не premature optimization, это идеология. Все что можно сделать в компайл тайме, там и нужно делать.)

Вариант 2.
Есть некий тег (код типа), НЕ известный на момент компиляции.
В этом случае имхо, только свитч, в том или ином виде. Конечно, он может быть довольно сильно завуалирован.
Точнее скажем так: какие-то движения по выбору пути в ран-тайме предпринять придется, по любасу.

PM MAIL   Вверх
Dem_max
Дата 22.10.2012, 04:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

Репутация: 4
Всего: 39



boostcoder
Ну как будто в шаблоне ты не будешь копипастить, копипастом пользоваться опасно, у же не раз тут человек из PVR-Studio  приводил примеры и предупреждал.


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
borisbn
Дата 22.10.2012, 05:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Ого сколько я пропустил...Сорри, сейчас с телефона смотрю. Как доберусь до десктопа обязательно отпишусь


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
borisbn
Дата 22.10.2012, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



В общем, задача следующая: имеется сериализованные бинарные данные примерно в таком формате
Код
1 байт - Назначение параметра
1 байт - Тип параметра (tag)
N байт - Значение параметра. N зависит от tag

В данном конкретном случае мне нужно просто распечатать назначение параметра (тут всё просто - берётся по таблице из 256 строк... или map - не важно) и собственно само значение параметра. Вот тут и загвоздка. Не то, чтобы непонятно как делать (решение на поверхности), сколько хотелось обойтись без свитча, но, судя по всему, не получится. В итоге сделал и с шаблонной функцией и со свитчем:
Код
template< class T >
void processValue( T value ) {
   cout << value;
}
template< class T >
void get( ucvect::iterator & it )
{
   T value = * ( (T*)(*it) );
   it += sizeof( T );
   processValue( value );
}
template<>
void get<std::string>( ucvect::iterator & it )
{
   std::string value( (*it) );
   it += value.length() + 1;
   processValue( value );
}
...
v_end = v.end();
while ( it != v_end ) {
   cout << param_names[ (*it) ] << ' : ';
   ++it;
   unsigned char tag = (*it);
   ++it;
   switch ( tag ) {
      case 0x1: get< unsigned char >( it ); break;
      case 0x2: get< unsigned short >( it ); break;
      case 0x3: get< int >( it ); break;
      case 0x4: get< std::string >( it ); break;
   }
}


Спасибо всем, кто ответил.

P.S. Сейчас перечитал тему и вижу, что создавать её было глупостью... на что надеялся - хз. На  smile, штоле...

Это сообщение отредактировал(а) borisbn - 22.10.2012, 08:40


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 22.10.2012, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

Репутация: 49
Всего: 110



Dem_max, в моем случае, копипастить буду не я, копипастить будет компилятор.

borisbn, да, если значение это чисто рантаймовская величина, то либо switch, либо map.

PM WWW   Вверх
math64
Дата 22.10.2012, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 8
Всего: 72



Если число различных типов параметров фиксировано - можно использовать паттерн Visitor (в данном случае, в его придётся модифицировать)
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0606 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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