Consider the ordered and unordered associative containers in C++ keyed on double
.
Is NaN
a valid key type?
With ordered containers, I should say "no", because it does not respect the strict weak ordering.
With unordered containers, I have no idea.
Here's what happens in GCC 4.6.2:
#include <map>
#include <unordered_map>
#include <cmath>
#include <iostream>
#include <prettyprint.hpp>
int main()
{
typedef std::map<double, int> map_type; // replace by "unorderd_map"
map_type dm;
double d = std::acos(5); // a good nan
dm[d] = 2;
dm[d] = 5;
dm[d] = 7;
std::cout << "dm[NaN] = " << dm[d] << ", dm = " << dm << std::endl;
}
For the ordered map, I get:
dm[NaN] = 7, dm = [(nan, 7)]
For the unordered map, I get:
dm[NaN] = 0, dm = [(nan, 0), (nan, 7), (nan, 5), (nan, 2)]
So in the ordered map, all NaNs are treated the same, which is what I expect, although it seemed like NaN would violate the requirements. For the unordered map, however, I can never retrieve an element again, and all NaNs are different. This is also not what I would expect.
Does the standard have to say anything on this matter?
Update: Thanks to the great answers below, note that the std::map
will break if you insert anything else into it once a NaN is in it.
(I'd be very grateful for comments on how other languages handle floating point keys in associative containers.)
See Question&Answers more detail:os