Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.06.2012, 16:43   #1
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию автоматический уникальный ID типа времени компиляции

Вопрос: можно ли добиться след. эффекта:

Код:
template<class T>
class Test
{
    //автоматическая генерация уникального для типа айдишника
    enum { eID =....}; //что можно подсунуть в правую часть выражения?
}
Требование: поддержка старого стандарта. Гцц/студия 2008.
_Bers вне форума Ответить с цитированием
Старый 17.06.2012, 21:22   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

имхо даже с constexpr это не сделать (именно с enum)
а вот в D без проблем

Код:
template Wrapper(T) {
public:
	enum { ID = cast(int)typeid(T) };
}

class A {}
class B {}
class C {}

writeln(Wrapper!A.ID);
writeln(Wrapper!B.ID);
writeln(Wrapper!C.ID);
можно хоть md5 или crc для имени класса в compile-time посчитать
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 17.06.2012, 23:00   #3
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
имхо даже с constexpr это не сделать (именно с enum)
а вот в D без проблем

Код:
template Wrapper(T) {
public:
	enum { ID = cast(int)typeid(T) };
}

class A {}
class B {}
class C {}

writeln(Wrapper!A.ID);
writeln(Wrapper!B.ID);
writeln(Wrapper!C.ID);
можно хоть md5 или crc для имени класса в compile-time посчитать
Так не должно скомпилировать, нельзя приводить ссылку на объект к int, нужно сначала привести к void*. и public - лишнее, в D всё public по умолчанию. И если перечисление содержит единственный элемент, то фигурные скобки можно опустить. Но вообще, сомнительный способ, имхо.
netrino вне форума Ответить с цитированием
Старый 17.06.2012, 23:08   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2netrino
http://ideone.com/Uv6wh
получается, что можно. может в d1 нельзя было? я вообще с языком не очень хорошо знаком, изучаю только.
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 17.06.2012, 23:15   #5
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
2netrino
http://ideone.com/Uv6wh
получается, что можно. может в d1 нельзя было? я вообще с языком не очень хорошо знаком, изучаю только.
Ах, действительно можно, но с оговоркой: тип должен быть не менее размера указателя на действующей платформе. У меня на 64-х битной системе нельзя было приводить к int, потому и сделал такие выводы, но сейчас проверил с long и действительно работает.
netrino вне форума Ответить с цитированием
Старый 18.06.2012, 09:48   #6
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

Говорят, что можно.
Знающий не говорит, говорящий не знает (С) Лао Цзы

Последний раз редактировалось Krok27; 18.06.2012 в 09:50.
Krok27 вне форума Ответить с цитированием
Старый 18.06.2012, 12:54   #7
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2Krok27
страна чудес молочных, блин))) но моя студия на работе (2003) больше 1400 значений не осиливает, ругается на глубину рекурсии.

хехе. а вот в gcc не работает
http://ideone.com/WFmFQ
первый вариант (с бустом) не проверял

хех. все куда проще
http://ideone.com/U8s8Z
только в каждом классе вручную нужно его определять, ибо при инстансах шаблона он ID не меняет, ибо тупо препроцессор
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 18.06.2012 в 13:11.
pproger вне форума Ответить с цитированием
Старый 18.06.2012, 14:37   #8
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

С бустом вроде пахает VS10:
Код:
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <iostream>

int engine(...);

template<bool f> struct ts
{
    typedef int type;
};

template<> struct ts<false>
{
    typedef char type;
};
 
#ifndef COUNTER_MAX_COUNT
#define COUNTER_MAX_COUNT 100
#endif

#define COUNTER_HELPER(z, n, text) , typename ts<(v>n)>::type

template<typename type>
struct cnt_unique {};

// генераторы
template<int id> struct lin_gen 
{
    static const int val = id;
};

template<int id> struct even_gen 
{
    static const int val = id * 2;
};

template<int id> struct lin_gen_down
{
    static const int val = -id;
};

template<int id> struct pow2_gen
{
    static const int val = 2 << id;
};

template<typename, template <int> class, int> struct cnt;
typedef cnt<cnt_unique<cnt_unique<void> >, lin_gen, 0> cntt;

template
<
    typename tag_t = void, 
    template <int> class gen_t = lin_gen,
    int id = sizeof(engine(*(cntt*)0, *(cnt_unique<tag_t>*)0, 
        BOOST_PP_ENUM_PARAMS(COUNTER_MAX_COUNT, (int))))
>
struct cnt
{
    static const int v = id / 4 - 1;
    friend int(&engine(cntt&, cnt_unique<tag_t>& BOOST_PP_REPEAT(COUNTER_MAX_COUNT, COUNTER_HELPER, _)))[v+2];
    static const int val = gen_t<v>::val;
};



int _tmain(int argc, _TCHAR* argv[])
{
	
	std::cout << cnt<>::val << std::endl; 
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;
	std::cout << cnt<>::val << std::endl;

	system("PAUSE");
	return 0;
}
gcc-4.3.4, правда, опять же не проглотил.
Изображения
Тип файла: jpg compilerandomgeneration.JPG (20.5 Кб, 66 просмотров)
Знающий не говорит, говорящий не знает (С) Лао Цзы

Последний раз редактировалось Krok27; 18.06.2012 в 15:06.
Krok27 вне форума Ответить с цитированием
Старый 18.06.2012, 14:58   #9
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2Krok27
в g++ нет
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 18.06.2012, 15:10   #10
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

2pproger
Ога.
Знающий не говорит, говорящий не знает (С) Лао Цзы
Krok27 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Уникальный идентификатор типа brag Общие вопросы C/C++ 10 17.06.2012 20:33
Определение типа класса по переменной на объект этого класса при компиляции phomm Общие вопросы Delphi 24 08.04.2011 14:11
ПОИСК В БД .DBF ПО ВРЕМЕНИ И ДАТЕ В ПОЛЕ ТИПА DATETIME ЛисЁНЫШ БД в Delphi 10 05.06.2010 21:02
Автоматический перевод времени с гринвича. Demien Общие вопросы Delphi 0 27.08.2009 12:02
Опредиление типа медиа-файла,времени его звучания Anatol_rus Мультимедиа в Delphi 2 13.11.2008 22:41