简体   繁体   English

如何在双精度数组上定义一个比较运算符(小于)?

[英]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 double parameters to my function call. 假设我的函数调用有2个double参数。

Those must be the key of some LRU cache or - to make it simpler - a C++ std::map . 那些必须是一些LRU缓存的关键,或者 - 使其更简单 - 一个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. 当尝试将其用作我的std::map一个键时,编译器抱怨,因为它需要一个operator<

.....\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). 如果我有6个参数怎么办(这是我的实际情况)。

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? 如果这是一个XY问题,是否有更简单的方法来创建具有double类型的n值键映射?

(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) (请注意,我完全清楚使用double值作为键看起来很糟糕,但我的目标是在函数调用上缓存值,其中参数完全相同,不打算存储或等等)

You are looking for std::lexicographical_compare 您正在寻找std::lexicographical_compare

bool operator<(const DoubleArray &other) const
{      
    return std::lexicographical_compare(array, array + n, other.array, other.array + n);
}

Alternatively, you can just define an alias to std::array , which already has all the comparison operators defined 或者,您可以只定义std::array的别名,该别名已经定义了所有比较运算符

template<int n>
using DoubleArray = std::array<double, n>;

You can sidestep the issue by using std::array . 您可以使用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;
}

How to create a generic comparison operator (maybe using template recursion) ? 如何创建通用比较运算符(可能使用模板递归)?

You can try this method: 你可以试试这个方法:

#include <utility>     // std::index_sequence
#include <tuple>       // std::tie

template <int N>
struct DoubleArray
{
private:
    template <size_t ... Is>
    bool opHelper(const DoubleArray& rhs, std::index_sequence<Is...>) const
    {
        return std::tie(arr[Is]...) < std::tie(rhs.arr[Is]...);
    }

public:
    double arr[N];

    bool operator<(const DoubleArray& rhs) const
    {
        return opHelper(rhs, std::make_index_sequence<N>{});
    }
};

Don't reinvent the wheel, use std::array. 不要重新发明轮子,使用std :: array。 It already has an overloaded operator<. 它已经有一个重载的运算符<。 Always consider using and combining what the standard library and other well known libraries offers before writing your own custom solution: Use libraries whenever possible . 在编写自己的自定义解决方案之前,请始终考虑使用和组合标准库和其他知名库提供的内容: 尽可能使用库

You may then declare your map like this: 然后,您可以像这样声明您的地图:

std::map<std::array<double, 2>, double> my_cache;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM