运营商LT;用于列表排序

时间:2012-11-22 06:07:30

标签: c++

我有一个简单的位置结构:

struct Position
{
    int x;
    int y;
};

我还有一份职位列表:

std::list<Position> positons;

我正在尝试使用list :: sort()对列表进行排序,并且需要定义operator&lt;对于Positions对象。我试着保持简单,创​​建类似的东西:

bool operator<(const Position& one, const Position& two)
{
    return one.x < two.x && one.y < two.y;
}

但这不起作用。如何确定一个类/结构对象整体小于另一个?我如何为我的Position结构做这件事?

编辑当我调用positions.sort()时,我得到一个调试断言失败,说: 表达式:无效的运算符&lt;

4 个答案:

答案 0 :(得分:3)

您当前的定义未建立strict weak order。尝试类似:

bool operator<(const Position& one, const Position& two)
{
    return std::tie(one.x, one.y) < std::tie(two.x, two.y);
}

这使用std::tie创建两个std::tuple<int const&, int const&>个对象,其中包含对xy的{​​{1}}和one元素的引用,然后使用operator<(执行lexicographical comparison)比较两个元组。

two需要C ++ 11,但使用boost::tuple可以获得类似的结果。

答案 1 :(得分:2)

您可以按原点或幅度的距离对您的位置进行排序,如下所示:

std::vector<Position> Foo;
std::sort(Foo.begin(), Foo.end(), [](Position& a, Position& b) {return (abs(a.x) + abs(a.y)) <  (abs(b.x) + abs(b.y)); });

答案 2 :(得分:1)

您可以按x排序,然后按y排序。同时将其定义为自由函数:

bool function(const Position& one, const Position& two)
{
    return one.x < two.x || (one.x == two.x && one.y < two.y);
}

operator

bool operator<(const Position& other)const
{
    return x < other.x || (x == other.x && y < other.y);
}

答案 3 :(得分:0)

最简单的解决方案是放弃struct并使用

typedef std::array< int, 2 > Position; // C++11, access pos[0] and pos[1]

typedef std::pair< int, int > Position; // C++03, access pos.first and pos.second

这些类预定义了operator<(以及您可能需要的所有其他运算符)。你无法调用坐标.x.y,但它比重新发明轮子更好。

如果您真的想要,还可以通过以下方式将std::array的成员称为xy

enum coord_name { x, y, z };

template< typename lhs_t >
auto operator ->* ( lhs_t &&lhs, coord_name rhs )
    -> decltype( lhs[ + rhs ] )
    { return lhs[ + rhs ]; }

Position coords;
std::array< float, 3 > coords_3d_floating;

// usage:
coords->*x = 8;
coords->*y = coords_3d_floating->*z * 1.5;

这需要C ++ 11。