我正在实现用于保存函数调用的缓存。
假设我的函数调用有2个reset_index(level=2, drop=True)
参数。
这些必须是某些LRU缓存的键,或者(为了使其更简单)是C ++ double
。
所以我创建了一个内部带有数组的模板类(值的数量可变)
std::map
当尝试将其用作我的template <int n>
class DoubleArray
{
public:
double array[n];
};
的键时,编译器抱怨,因为它需要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; }
~~~~^~~~~
请注意,比较运算符非常笨拙。如果我有6个参数(这是我的实际情况)怎么办?
如何创建通用比较运算符(可能使用模板递归)?
如果这是XY问题,是否有更简单的方法来创建具有#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;
}
类型的n值键映射?
(请注意,我完全意识到使用double
值作为键看起来很糟糕,但是我的目标是在函数调用中缓存值完全相同的参数,而不打算将其存储或存储。这样)
答案 0 :(得分:8)
您正在寻找std::lexicographical_compare
bool operator<(const DoubleArray &other) const
{
return std::lexicographical_compare(array, array + n, other.array, other.array + n);
}
或者,您可以只定义std::array
的别名,该别名已经定义了所有比较运算符
template<int n>
using DoubleArray = std::array<double, n>;
答案 1 :(得分:4)
您可以使用std::array
来回避问题。使用alias declaration,您的代码可以简化为
artists = [
{"artistName": "Nirvana", "artistID": "0001", "album": "Nevermind"},
{"artistName": "Pearl Jam", "artistID": "0201", "album": "Ten"},
{"artistName": "Alice In Chains", "artistID": "1192", "format": "Sap"}
]
found_artist = artists.find do |artist|
artist[:artistName] == "Nirvana"
end
artistID = found_artist[:artistID]
puts artistID
答案 2 :(得分:2)
如何创建通用比较运算符(可能使用模板递归)?
您可以尝试以下方法:
#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>{});
}
};
答案 3 :(得分:2)
不要重新发明轮子,请使用std :: array。它已经有一个重载的operator <。在编写自己的自定义解决方案之前,请始终考虑使用标准库和其他知名库提供的功能并将其组合:Use libraries whenever possible。
您可以这样声明地图:
std::map<std::array<double, 2>, double> my_cache;