Самый безопасный способ идентификации уникального типа в С++ 11

Где-то при формировании нового стандарта было обещано более легкое использование type_info, что, среди прочего, привело к реализации hash_code. Однако при реализации системы отражения в C++11 я снова столкнулся с проблемой уникальной идентификации типа.

Я нуждаюсь:

  1. Что-то, что позволит мне извлечь из типа уникальный идентификатор typeid
  2. Уникальный идентификатор должен иметь возможность использоваться в контейнере ключ/значение.
  3. Идентификатор не должен быть переносимым или даже одинаковым между выполнениями программы.

Обратите внимание, что мне не нужно постоянство между запусками программы. Как это выглядит:

  1. .name() совершенно бесполезен, потому что стандарт не дает на него никаких гарантий.
  2. .hash_code() также бесполезен, потому что не гарантируется его уникальность.
  3. Использование указателя на объект type_info не будет работать везде (например, в DLL)
  4. Только .before() кажется полезным - хотя я не знаю, не будет ли он страдать от той же проблемы, что и № 3.

Даже если будет использоваться .before(), то мы можем использовать map, а я бы предпочел использовать unordered_map.

struct compare_type_info {
    bool operator ()(const type_info* a, const type_info* b) const {
        return a->before(*b);
    }
};
std::map<const type_info*, X, compare_type_info> map;
m[&typeid(int)] = something;

Является ли вышеуказанное безопасным для столкновения? Гарантирует ли оператор упорядочивания перезапись значений !‹ и !>?

Есть ли способ решить эту проблему без риска коллизии хэшей?

Что касается свертывания моей собственной системы типов, я уже это делаю, но typeid решает проблемы с получением правильного конечного типа из базового типа (наследование), и я не хочу добавлять какие-либо поля в свои классы (система типов " внешний").

Даже в C++11 мы все еще облажались? :/


person Kornel Kisielewicz    schedule 01.06.2013    source источник
comment
было обещание упростить использование type_info Нет, не было. И это не то, для чего нужен hash_code.   -  person Nicol Bolas    schedule 01.06.2013
comment
Кроме того, есть ли какая-то причина, по которой вы не можете использовать сам type_info?   -  person Nicol Bolas    schedule 01.06.2013
comment
@Nicol, я хочу добавить больше информации о типе (отражение).   -  person Kornel Kisielewicz    schedule 01.06.2013
comment
Я получил эту часть. Почему вы не можете использовать type_info для этого? Почему вы не можете использовать его в качестве ключа в unordered_map?   -  person Nicol Bolas    schedule 01.06.2013
comment
У меня есть указатель объекта * - я хочу получить доступ к своей базе данных типов, поэтому мне нужно получить из указателя объекта * указатель реального типа (производный *), AFAIR нет другого пути, кроме как через typeid(). Итак, мне нужен индекс typeid -> информация о моем типе. Однако информация о типе может быть расширена во время выполнения, поэтому она не может иметь дубликатов и всегда должна быть возвращена.   -  person Kornel Kisielewicz    schedule 01.06.2013
comment
информация о типе может быть расширена во время выполнения Что вы имеете в виду?   -  person Nicol Bolas    schedule 01.06.2013
comment
Моя собственная информация о типе может быть расширена другими модулями, добавляющими дополнительную информацию о том, как обрабатывать этот тип.   -  person Kornel Kisielewicz    schedule 02.06.2013


Ответы (1)


Вы можете использовать std::type_index, который можно построить из std::type_info. Они полностью упорядочены и реализуют все реляционные операции. type_index можно даже неявно преобразовать из type_info.

person Nicol Bolas    schedule 01.06.2013
comment
Это кажется тем, что я ищу... но, просматривая последний черновик, кажется, что стандарт не дает никаких гарантий его уникальности? - person Kornel Kisielewicz; 01.06.2013
comment
Следовательно, если для типа A и типа B тип A = тип B, гарантирует ли это, что оператор == (A, B) равен true даже в разных DLL? - person Kornel Kisielewicz; 01.06.2013
comment
Стандарт абсолютно ничего не говорит о разных DLL. Но я ожидаю, что они будут работать таким образом. - person aschepler; 01.06.2013
comment
К сожалению, он ничего не говорит об уникальности экземпляров type_info, и это лучший пример, который я могу привести, который делает их неуникальными :/. - person Kornel Kisielewicz; 01.06.2013
comment
@KornelKisielewicz: это ничего не говорит об уникальности экземпляров type_info С чего бы это? Важно содержимое файла type_info. Если два экземпляра type_info ссылаются на один и тот же тип, то они равны. Если нет, то они будут иметь произвольный порядок. Что вы еще хотите? - person Nicol Bolas; 01.06.2013
comment
Я хочу однозначно идентифицировать каждый тип, чтобы добавить к нему метаинформацию. - person Kornel Kisielewicz; 02.06.2013
comment
@KornelKisielewicz: И как type_info этого не сделать? Где в стандарте разрешено сравнение двух объектов type_info, относящихся к разным типам, равных? - person Nicol Bolas; 02.06.2013
comment
Насколько я знаю, это не запрещает два вызова typeid для возврата разных объектов type_info. - person Kornel Kisielewicz; 02.06.2013
comment
@KornelKisielewicz: Подожди. Стандарт очень четко говорит для operator==, true, если два значения описывают один и тот же тип. И вы интерпретируете это как не идентификацию типа? - person Nicol Bolas; 02.06.2013
comment
@KornelKisielewicz Вам не нужна уникальность, и никто из std::type_info или std::type_index не полагается на нее. - person Luc Danton; 02.06.2013
comment
@Nicol, в большинстве других логических возвратов в стандарте, за которым в противном случае следует false. Здесь не тот случай, но я думаю, что это все, что я могу получить гарантию. См. это обсуждение - stackoverflow.com/questions/1819114/ - person Kornel Kisielewicz; 02.06.2013
comment
Вопрос в том, переходит ли эта слабость к оператору ==? Не испортит ли это unordered_map на основе type_index? - person Kornel Kisielewicz; 02.06.2013
comment
@KornelKisielewicz: в большинстве других логических значений в стандарте возвращается значение false, в противном случае Нет, во многих других логических значениях это сказано. В некоторых нет. Например, operator== из std::thread так не говорит. - person Nicol Bolas; 02.06.2013
comment
@KornelKisielewicz: Посмотрите это обсуждение Это обсуждение совершенно не имеет значения. Откуда берется память для конкретного экземпляра type_info, не имеет значения. Важно то, что согласно стандарту происходит, когда они сравниваются равными. - person Nicol Bolas; 02.06.2013
comment
Согласованный. Спасибо за терпение :) - person Kornel Kisielewicz; 02.06.2013