我想通过主要字段对结构的向量进行排序,并使用辅助字段作为打破平局。通常的方式是:
struct element {
int primary;
int secondary;
};
bool comparator(const element& e1, const element& e2) {
if (e1.primary != e2.primary) {
return e1.primary < e2.primary;
}
return e1.secondary < e2.secondary;
}
但是二级数据的计算成本很高。因为它仅在主值相等时才需要,我想懒惰地计算它。
似乎我唯一可以做这个懒惰评估的地方就是比较器本身。类似的东西:
bool comparator(const element& e1, const element& e2) {
if (e1.primary != e2.primary) {
return e1.primary < e2.primary;
}
return e1.computeSecondary() < e2.computeSecondary();
}
虽然这将避免在主值不同的情况下评估次要值,但每次与另一个元素进行比较时,它将最终重新计算同一元素的次要值。我想要排序的数据是长尾的,其中30%的值等于1,20%等于2,5%等于3,较高的值为%。因此,将会有相当多的情况会计算次要元素,而不存储计算值可能导致重新计算次数。
所以,我希望每个元素最多评估一次二次值。但是比较器采用const ref参数,因此它不能修改元素的二次值。如何实现这一目标?
答案 0 :(得分:3)
简而言之,可能的选择。
secondary
mutable。const_cast
。{/ li>中使用comparator
const_cast
。{/ li>中使用computeSecondary
Lazy
模板类,该类可以包含值或thunk,并且在被要求时,如果尚未评估值,则在内部强制执行值并报告结果(或立即报告结果,如果它已经知道),不需要很长时间;并声明类型为secondary
的{{1}}。Lazy<int>
实际上是非常懒惰的模板(在一种情况下)。