一般严格弱序比较谓词模板函数

General strict weak order comparison predicate template function

本文关键字:谓词 函数 比较      更新时间:2023-10-16

为了克服重复,我编写了一个模板化的严格弱排序谓词,以使其更容易。

通常当需要多个字段和/或每个字段需要不同的顺序(ASC/DESC)来对容器进行排序时,我们必须创建自定义比较谓词,这些谓词有时会根据实现变得空白或复杂。

例如(3个字段)

if(lhs->IsOnline() == rhs->IsOnline())
{
    if(lhs->GetLowestRankIndex() == rhs->GetLowestRankIndex())
        return lhs->GetName() < rhs->GetName();
    else
        return lhs->GetLowestRankIndex() > rhs->GetLowestRankIndex();
}
else
    return lhs->IsOnline() > rhs->IsOnline();

或其不那么空但有点复杂的等效

return lhs->IsOnline() > rhs->IsOnline() || (lhs->IsOnline() == rhs->IsOnline()
    && (lhs->GetLowestRankIndex() > rhs->GetLowestRankIndex() || (lhs->GetLowestRankIndex() == rhs->GetLowestRankIndex()
    && lhs->GetName() < rhs->GetName())));

现在我想问一个与可变模板相关的问题。正如你可能已经注意到的那样,在我的回答中,我不得不在基本函数中添加未使用的可变typename..._,并在主函数中添加额外的typename... Tail,因为我无法设置尾参数的类型,因为2个参数使用相同的类型,然后在参数包中继续进行下一次。虽然它可以工作,但我并不完全满意它,因为它破坏了IDE的错误检测(至少在VS中)。

由于每个比较类型必须发送2个参数到函数,我找不到任何其他方法。是否有可能使模板类型推导期望一个参数包有2个参数?

template <typename Compare, typename..._>
bool SWOPredicate(const typename Compare::first_argument_type &lhs,
    const typename Compare::second_argument_type &rhs)
{
    Compare cmp;
    return cmp(lhs, rhs);
}
template <typename CompareHead, typename... CompareTail, typename... Tail>
bool SWOPredicate(const typename CompareHead::first_argument_type &lhs,
    const typename CompareHead::second_argument_type &rhs,
    const Tail &...tail)
{
    CompareHead cmp;
    return cmp(lhs, rhs) || (lhs == rhs && SWOPredicate<CompareTail..., Tail...>(tail...));
}
使用

return SWOPredicate<std::greater<bool>, std::greater<int>, std::less<std::string>>
    (lhs->IsOnline(), rhs->IsOnline(),
    lhs->GetLowestRankIndex(), rhs->GetLowestRankIndex(),
    lhs->GetName(), rhs->GetName());