Я не думаю, что есть какой-либо способ генерировать индексы во время компиляции, за исключением использования enum
(что я бы рассмотрел вполне разумный подход). Я не уверен, что шаблон поможет, потому что шаблоны являются чисто функциональными, и хранить глобальное состояние (т. Е. Текущий индекс) некуда, кроме как в имени самого шаблонного типа (именно это вы пытаетесь избегать).
Если вам действительно нужны идентификаторы целых чисел, возможно, проще всего настроить их во время выполнения, а не пытаться слишком усердно.
Во-первых, имейте объект, представляющий тип, и используйте типичный подход, сделанный вручную: RTTI: у каждого класса есть статический экземпляр этого объекта и его виртуальная функция get-type-info возвращает указатель на этот объект. Таким образом, каждый класс будет иметь немного коды в нем, как это:
static TypeInfo ms_type_info;
virtual const TypeInfo *GetTypeInfo() const {
return &ms_type_info;
}
И вы бы определить данные типа, ввод в секцию любой информации <<whatever you info you want>>
в TypeInfo
магазины прочь, чтобы сделать его лучше, чем компилятор RTTI;
TypeInfo WhateverClass::ms_type_info(<<whatever info you want>>);
(Каждая реализация я видел это использует макрос для автоматизации создания этих двух битов текста, немного некрасиво, но ваши возможности ограничены, и это лучше, чем печатать его.)
TypeInfo
сама структура будет выглядеть немного так:
struct TypeInfo {
int type_index;
TypeInfo *next;
TypeInfo(<<whatever>>) {<<see below>>}
};
Если читатель предпочел бы получить и установить функции, он может иметь те.
Объект TypeInfo
должен быть статичным для класса, а не функцией, поскольку целью является создание списка всех TypeInfos
. У вас есть два варианта. Автоматический должен иметь каждый TypeInfo
, в конструкторе, который был оставлен пустым выше, добавить себя в какой-то глобальный связанный список; другой должен иметь большую функцию, которая добавляет те, которые она хочет к глобальному списку вручную.
Затем, при запуске, пройдите через объекты TypeInfo
и назначьте каждый индекс. Что-то, как это будет делать, если предположить, что есть TypeInfo *g_first_type_info
, что указывает на первую информацию типа в списке:
int next_type_index=0;
for(TypeInfo *ti=g_first_type_info;ti;ti=ti->next)
ti->type_index=next_type_index++;
Теперь, когда вы хотите, чтобы ваш целочисленный идентификатор, вы можете получить его легко:
object->GetTypeInfo()->type_index;
Вы могли бы реализовать t
достаточно легко в настоящее время:
virtual int t() const {
return ms_type_info.type_index;
}
Полное раскрытие проблем, я могу думать:
Индексы типов не установлены во время компиляции, поэтому, если вы создаете массивы, вам нужно будет их создать во время выполнения. Это может быть пустой тратой кода, если ваши массивы в противном случае были бы компиляцией констант времени, однако для компиляторов, которые не поддерживают синтаксис инициализации массива в стиле C99, это может иногда сделать код более читаемым.
Если вы хотите сделать все, что в глобальных конструкторов, прежде чем main
начинается, вы можете отклеилась, как TypeInfo
объекты являются обычными глобальными объектами и (в этой ситуации так или иначе) не должным образом не готовы к использованию в любом случае до тех пор, типа индексы были назначены.
Линкеры имеют тенденцию выделять глобальные объекты, которые, как представляется, не используются, поэтому объекты типа info в статических библиотеках никогда не могут добавить себя в список. Поэтому вы должны иметь в виду, что, хотя подход автоматической регистрации работает хорошо, когда он не работает, он этого не делает, поэтому в любом случае вы можете вручную регистрировать вещи вручную.
для чего вы хотите этого? – 2010-12-04 12:02:52
Некоторые компиляторы предоставляют макросы препроцессора, которые расширяются до нового целого числа каждый раз, когда они используются в одном и том же ТУ. Кроме этого, я думаю, вам не повезло с этим. Тем не менее, он просто задает вопрос: «Если вы хотите RTTI, то почему бы вам не использовать RTTI? _ – sbi 2010-12-04 12:08:05
Это в основном улучшить мои навыки с помощью шаблонов и понять новые способы их использования. Кроме того, это упростит мой код: на данный момент у меня есть те функции A :: t`, которые жестко закодированы вручную. Мне нужны эти интегральные значения, идентифицирующие типы для создания контейнера, который связывает тип с указателем функции; если эти целые числа непрерывны, я могу использовать массив, иначе вам понадобится таблица карт/хэшей, и я бы предпочел избежать. – peoro 2010-12-04 12:12:36