Фон
Требование для компаратора по типу ключа ассоциативного контейнера (например, std:: map) заключается в том, что он налагает строгий слабый порядок на элементы типа ключа.
Для данного компаратора comp(x, y) определим equiv(x, y) = !comp(x, y) && !comp(y, x).
Требования к comp(x, y), являющиеся строгим слабым порядком,
- Irreflexibility (
!comp(x, x)для всехx) - Транзитивность упорядочения (если
comp(a, b)иcomp(b, c), затемcomp(a, c)). - Транзитивность эквивалентности (если
equiv(a, b)иequiv(b, c), затемequiv(a, c))
std::less<float> (компаратор по умолчанию) использует operator<, который не создает строгий слабый порядок из-за NaN. Поскольку x < NaN и NaN < x являются ложными для всех x, NaN эквивалентно всем поплавкам под этим компаратором, это нарушает условие # 3: equiv(1.0, NaN) и equiv(NaN, 2.0), но не equiv(1.0, 2.0). Для поплавков IEEE, кроме NaN, это строгий слабый порядок (где каждое число имеет свой собственный класс эквивалентности, за исключением 0 и -0).
Вопрос
Означает ли это, что стандартом С++ не разрешено использовать IEEE-поплавки (и (длинные) удвоения) в качестве типа ключа в ассоциативном контейнере из-за вышеупомянутой проблемы, даже если я убеждаюсь, что NaN никогда не вставлен в контейнер? Я не совсем уверен в формулировке "элементов Key" в стандарте - если это означает все возможные элементы или просто элементы, которые попадают в контейнер.
Примечание. Вопрос не в проблемах. усечение/округление, я скорее всего опубликую другой вопрос относительно этого в ближайшее время.
Обновление:
Вздох. Я должен был задать вопрос без указания float, я просто подумал, что это хороший пример.
Вопрос действительно: разрешено ли использовать компаратор, который налагает только строгий слабый порядок на элементы, которые помещаются в контейнер, а не все возможные экземпляры типа ключа? Пожалуйста, не просто ответьте "да" или "нет", я бы хотел, чтобы некоторые ссылки на стандартные/предыдущие обсуждения об этом/ответ от члена сообщества или что-то в этом роде.