为类的元素定义字典比较的最简单方法是什么?

时间:2010-03-23 14:28:11

标签: c++ lexicographic

如果我有一个我希望能够排序的类(即支持一个小于概念),并且它有几个数据项,我需要做词典排序,那么我需要这样的东西:

struct MyData {
  string surname;
  string forename;

  bool operator<(const MyData& other) const {
    return surname < other.surname || (surname==other.surname && forename < other.forename); }
};

对于拥有2个以上数据成员的任何内容,这变得非常难以管理。有没有更简单的方法来实现它?数据成员可以是任何Comparable类。

4 个答案:

答案 0 :(得分:10)

tuple是一个好主意,但是如果你想为你的成员变量保留名字,那么重组你的比较函数可能就好了:

struct MyData {
    string surname;
    string forename;
    string var;
    // ...

    bool operator<(const MyData& other) const {
        if (surname != other.surname) return surname < other.surname;
        if (forename != other.forename) return forename < other.forename;
        if (var != other.var) return var < other.var;

        // ...

        return false; //< They are equal
    }
};

根据您的喜好,您甚至可能需要像#define COMPARE(field) if (field != other.field) return field < other.field;这样的宏来减少重复。然后该函数将成为COMPARE - 调用的列表。

答案 1 :(得分:6)

您可以将数据存储在boost::tuple中,该#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple_comparison.hpp> struct Data { string &surname() {return stuff.get<0>();} string &forename() {return stuff.get<1>();} // it would be polite to add const overloads too. bool operator<(const Data &other) const {return stuff < other.stuff;} private: boost::tuple<string, string> stuff; }; 提供字典比较,并提供命名的访问者功能,如下所示:

std::tr1::tuple

我相信这也可以std::tuple获得,并且在即将推出的标准中将会{{1}}。

维护访问者列表可能比维护比较代码更易于管理。

答案 2 :(得分:3)

如果所有成员都具有相同的类型,您可以将它们放在std::vector中。默认情况下,std::lexicographical_compare将用于比较矢量。

答案 3 :(得分:2)

您可以使用内置词法比较的boost::tuplestd::pair。当然缺点是你不能将方法与元组关联起来。