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

Поиск:

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


Эксперт
****


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

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



Здравствуйте.
Хочу получить следующий код
Код
template< unsigned char Tag >
struct tag_2_type;

#define TAG_2_TYPE( Tag, Type ) template<> struct tag_2_type< Tag > { typedef Type type; }
TAG_2_TYPE( 0x1, unsigned char );
TAG_2_TYPE( 0x2, unsigned short );
TAG_2_TYPE( 0x3, int );
TAG_2_TYPE( 0x4, std::string);

void foo( unsigned char tag, void * p )
{
    typedef typename tag_2_type< tag >::type tag_t;
    tag_t value = *( (tag_t*)p );
    cout << value;
}

...
   unsigned char c;
   foo( 0x1, &c );
   int i;
   foo( 0x3, &i );

http://liveworkspace.org/code/0abd4f6bcc30...acb606b53230b5e
ессно, это не работает.
Код
error: 'tag' is not a constant expression

выход, конечно, есть - сделать через switch, но хотелось бы как-нить поэлегантнее.
Есть ли вообще возможность создать одной строкой такой тип tag_t ?
Спасибо.


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


pattern`щик
****


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

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



думаю, это единственный способ:
Код

#include <iostream>
#include <string>

using std::cout;
using std::endl;

enum class e_tags: unsigned char {
    e1 = 1
   ,e2 = 2
   ,e3 = 3
   ,e4 = 4
};

template<e_tags>
struct tag_2_type;

#define TAG_2_TYPE( Tag, Type ) \
template<> \
struct tag_2_type<Tag> { \
   typedef Type type; \
}

TAG_2_TYPE(e_tags::e1, unsigned char);
TAG_2_TYPE(e_tags::e2, unsigned short);
TAG_2_TYPE(e_tags::e3, int);
TAG_2_TYPE(e_tags::e4, std::string);

template<e_tags tag>
void foo(void* p) {
   typedef typename tag_2_type<tag>::type tag_t;
   tag_t value = *( (tag_t*)p );
   cout << value << std::endl;
}

int main() {
   int i = 44;
   unsigned char c = 'z';

   foo<e_tags::e1>(&c);
   foo<e_tags::e3>(&i);
}


http://liveworkspace.org/code/61f1dbf44267...340c21c4675be47

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

Это сообщение отредактировал(а) boostcoder - 21.10.2012, 15:24
PM WWW   Вверх
Dem_max
Дата 21.10.2012, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

   foo<e_tags::e1>(&c);
   foo<e_tags::e3>(&i);

ЭЭЭэ, ну и нафига тогда надо было весь этот паровоз городить ??? мы уже тип передали в виде e1, e3


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


Эксперт
****


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

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



Именно так и сделал в итоге. Думал, просто, что можно как-нибудь поэлегантнее...


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


pattern`щик
****


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

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



Цитата(Dem_max @  21.10.2012,  15:25 Найти цитируемый пост)
тип передали в виде e1, e3

e1 и e3 это не типы, это ключи.

Добавлено через 42 секунды
Цитата(borisbn @  21.10.2012,  15:25 Найти цитируемый пост)
Думал, просто, что можно как-нибудь поэлегантнее... 

думаю можно. но задача не известна.

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


Эксперт
***


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

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



Цитата

e1 и e3 это не типы, это ключи.

Да ты хоть как их закодируй и обзови. Суть от этого не меняется, тип передан в зашифрованном виде


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


pattern`щик
****


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

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



Dem_max, ты под веществами?

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


Эксперт
***


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

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



Код

enum
{
    e1 = 1 //unsigned char
   ,e2 = 2 //unsigned short
   ,e3 = 3 //int
   ,e4 = 4 //std::string
};

void foo(int type, void *)
{
    switch(tyte)
    {
        case e1: cout << "type as unsigned char, как ты угадал ???" << std::endl; break;
        case e2: cout << "type as unsigned short, как ты угадал ???" << std::endl; break;
        case e3: cout << "type as int, как ты угадал ???" << std::endl; break;
        case e4: cout << "type as std::string, как ты угадал ???" << std::endl; break;
    }
}

int main() 
{
   int i = 44;
   unsigned char c = 'z';

   foo(e3, &c);
   foo(e1, &i);

   // Поразительно программа угадывает 
}



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


pattern`щик
****


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

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



Dem_max, снимай свой шлем хоть иногда, моцг проветривать.
Цитата(borisbn @  21.10.2012,  14:12 Найти цитируемый пост)
выход, конечно, есть - сделать через switch, но хотелось бы как-нить поэлегантнее.


Добавлено @ 15:52
Dem_max, или, возможно ты не понимаешь, почему решение со switch это грёбанный костыль, и почему ТС хотел его избежать?



Это сообщение отредактировал(а) boostcoder - 21.10.2012, 15:52
PM WWW   Вверх
Dem_max
Дата 21.10.2012, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

почему решение со switch это грёбанный костыль

Расскажи почему ???


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


pattern`щик
****


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

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



как минимум потому, что для того чтоб добавить новый тип, ему придется лезть в эту функцию. и так каждый раз.
и представь, какого размера будет этот switch, если к примеру, ТС`у нужно кастить хотя бы в 30 типов.

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


Эксперт
***


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

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



В твоем коде добавлять столько же строчек как и в мой, чем же твой код лучше от этого стал ??


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


pattern`щик
****


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

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



значит ты не видишь разницу.
лень объяснять. может кто-то другой объяснит.

borisbn, кстати, твою задачу можно решить более элегантно, с использованием boost.preprocessor.
наперед, предвижу что-то вроде:
Код

CREATE_TYPES_MAP(
   my_enum_name,
   ((unsigned char))
   ((unsigned short))
   ((unsigned int))
   ((std::string))
);

т.е. этот макрос будет одновременно генерить енум-ключей с именем my_enum_name, и специализации tag_2_type<> для перечисленных типов/ключей.



Это сообщение отредактировал(а) boostcoder - 21.10.2012, 16:31
PM WWW   Вверх
W4FhLF
Дата 21.10.2012, 20:46 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


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

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



Цитата(boostcoder @  21.10.2012,  16:29 Найти цитируемый пост)
значит ты не видишь разницу.
лень объяснять. может кто-то другой объяснит.


Я тоже не вижу. В данном конкретном случае, без уточнения деталей задачи, switch проще и требует меньше кода, зачем тут городить что-то ещё непонятно.
Может кто-нибудь не поленится и объяснит?


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


pattern`щик
****


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

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



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


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

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