Search code examples
c++dictionarycomparison-operators

how to define a comparison operator (less than) on array of doubles?


I'm implementing a cache to save function calls.

Let's say I have 2 doubleparameters to my function call.

Those must be the key of some LRU cache or - to make it simpler - a C++ std::map.

So I created a template class with the array inside (variable number of values)

template <int n>
  class DoubleArray
  {
    public:   
    double array[n];
   };

When trying to use that as a key of my std::map, the compiler complained because it needed a operator< for those.

.....\include\c++\7.3.1\bits\stl_function.h:386:20: note:
'const DoubleArray<2>' is not derived from 'const std::map<_Key, _Tp, _Compare,
_Alloc>'
       { return __x < __y; }
                ~~~~^~~~~

So I implemented a comparison operator (well, I though that hashing could do the trick but it doesn't seem so...) and it compiled:

#include <map>

template <int n>
  class DoubleArray
  {
    public:   
    double array[n];
    bool operator<(const DoubleArray &other) const
    {      
      return (array[0] < other.array[0]) || (array[0] == other.array[0] && array[1] < other.array[1]);
    }

  };

int main()
{
   std::map<DoubleArray<2>,double> my_cache;
   DoubleArray<2> params;
   // clumsy way to initialize the array...
   params.array[0] = 12;
   params.array[1] = 2;
   // put a value in cache
   my_cache[params] = 23;
}

Note that the comparison operator is really clumsy. What if I have 6 parameters (which is my real case).

How to create a generic comparison operator (maybe using template recursion) ?

In case this is a XY problem, is there a simpler way to create a n-value key map with double types?

(note that I'm fully aware that using double values as keys looks bad, but my goal is to cache values on function calls where the parameters are exactly the same, those are not intended to be stored or such)


Solution

  • You can sidestep the issue by using std::array. Using an alias declaration your code could be simplified to

    template <std::size_t N>
    using DoubleArray = std::array<double, N>;
    
    int main()
    {
       std::map<DoubleArray<2>,double> my_cache;
       my_cache[{12, 2}] = 23;
    }