Background
The requirement for a comparator on the key type of an associative container (for example std::map) is that it imposes a strict weak order on the elements of the key type.
For a given comparator comp(x, y) we define equiv(x, y) = !comp(x, y) && !comp(y, x).
The requirements for comp(x, y) being a strict weak order are
- Irreflexibility (
!comp(x, x)for allx) - Transitivity of the ordering (if
comp(a, b)andcomp(b, c)thencomp(a, c)). - Transitivity of equivalence (if
equiv(a, b)andequiv(b, c)thenequiv(a, c))
std::less<float> (the default comparator) uses operator<, which does not create a strict weak order because of NaN. Because x < NaN and NaN < x are false for all x, NaN is equivalent to all floats under this comparator, this breaks condition #3: equiv(1.0, NaN) and equiv(NaN, 2.0) but not equiv(1.0, 2.0). For IEEE floats except NaN, it is a strict weak order (where each number has its own equivalence class except for 0 and -0).
The question
Does this mean that one is not allowed by the C++ standard to use IEEE floats (and (long) doubles) as a key type in an associative container because of the above issue, even if I make sure that NaN never gets inserted into the container? I'm not quite sure about the "elements of Key" wording in the standard—if it means all possible elements or just the elements that end up in the container.
Note: The question is not about issues wrt. truncation/rounding, I'll likely post a different question regarding that soon.
Update:
Sigh. I should've posed the question witho