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

the*_*ill 12 c++ lexicographic

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

struct MyData {
  string surname;
  string forename;

  bool operator<(const MyData& other) const {
    return surname < other.surname || (surname==other.surname && forename < other.forename); }
};
Run Code Online (Sandbox Code Playgroud)

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

Mag*_*off 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
    }
};
Run Code Online (Sandbox Code Playgroud)

根据您的喜好,您甚至可能希望宏#define COMPARE(field) if (field != other.field) return field < other.field;来减少重复.然后该函数将成为COMPARE-invocations 列表.


the*_*ill 8

随着C++ 11的出现,使用std :: tie实现这一目标有一种全新而简洁的方法:

bool operator<(const MyData& other) const {
  return std::tie(surname, forename) < std::tie(other.surname, other.forename);
}
Run Code Online (Sandbox Code Playgroud)


Mik*_*our 6

您可以将数据存储在a中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;
};
Run Code Online (Sandbox Code Playgroud)

我相信这也可用std::tr1::tuple,并将std::tuple在即将出台的标准中.

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

  • 你可以保留命名字段并仅使用元组进行比较,例如`return boost :: tie(surname,forename)<boost :: tie(other.surname,other.forename);` (4认同)
  • 更好的是,在成员函数中包装`tie`.然后你只需要维护一个词典顺序列表. (2认同)