13

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

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

5 回答 5

12

随着 C++11 的出现,使用std::tie有了一种新的简洁的方法来实现这一点:

bool operator<(const MyData& other) const {
  return std::tie(surname, forename) < std::tie(other.surname, other.forename);
}
于 2015-08-25T09:44:30.883 回答
11

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

于 2010-03-23T14:53:25.870 回答
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;
};

我相信这也可以作为std::tr1::tuple,并将std::tuple在即将发布的标准中。

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

于 2010-03-23T14:40:35.927 回答
3

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

于 2010-03-23T14:47:56.053 回答
2

您可以使用boost::tupleor std::pairwhich 具有内置的字典比较。当然,缺点是您不能将方法与元组相关联。

于 2010-03-23T14:36:11.677 回答