通过 std::rel_ops 专业化 std::greater

specialize std::greater via std::rel_ops

如何使用 std::rel_ops 来专精 std::greater? 我有这样的东西

#include <utility>
#include <functional>

using namespace std::rel_ops;

struct MyStruct {
    int field;
    bool operator < (const MyStruct& rhs) const {
        return field < rhs.field;
    }
};

所以我需要按降序对元素进行排序。如何使用 operator <std::rel_opsstd::greater?

你必须这样做:

std::vector<MyStruct> v{...};

std::sort(v.begin(), v.end(), [](const MyStruct& lhs, const MyStruct& rhs){
    using namespace std::rel_ops;
    return lhs > rhs;
});

虽然 std::rel_ops 很蹩脚。使用boost::less_than_comparable更简单,直接把运算符加到MyStruct:

struct MyStruct 
    : boost::less_than_comparable<MyStruct> // <== adds operator>,
                                            //          operator>=, 
                                            //      and operator<=
{
    MyStruct(int i) : field(i) { }
    int field;

    bool operator<(const MyStruct& rhs) const {
        return field < rhs.field;
    }
};

然后您可以按明显的方式对其进行排序:

std::sort(v.begin(), v.end(), std::greater<MyStruct>());

std::rel_ops 从 ==< 生成其他比较,因此您首先需要至少定义 <

bool operator<(const MyStruct & lhs, const MyStruct & rhs) {
    return lhs.field < rhs.field;
}

现在 rel_ops 生成 > 所以现在你可以在 std::sort

中使用 std::greater
std::sort(begin(myVector), end(myVector), std::greater<MyStruct>());

我假设你试图做类似于

的事情
MyStruct ms[] = {{10}, {50}, {30}, {20}};
std::sort(std::begin(ms), std::end(ms), std::greater<MyStruct>{});

编译失败,因为找不到合适的operator>。这是因为 std::greater 依赖 ADL 来查找运算符重载,并且 ADL 在关联的命名空间中进行搜索。 std::rel_ops 不是 MyStruct 的关联命名空间。您可以通过将 using 声明添加到与 MyStruct 相同的名称空间来使一切正常工作,以便找到相关的 operator>

using std::rel_ops::operator>;

Live demo

但这很丑陋,而且通常不是一个可行的解决方案,所以忘记 std::rel_ops 并使用 Boost.Operators as