C ++无法排序自定义对象的向量

时间:2014-04-28 00:29:00

标签: c++ sorting object vector duplicates

编辑,更新:很棒的答案谢谢大家。我为&lt;写了运算符重载和==运算符。我不再收到错误。我也正确地通过引用而不是通过值将向量传递给我的removeDup(vector<Graph::Vertex>&);函数。

我有一个对象向量,我需要删除重复项,但我收到一个我不熟悉的错误(错误如下)。它是一个非常简单的对象,公开包含在名为Graph的类中:

struct Vertex
    {
        string name;
        int num;
    public:
        Vertex();
        Vertex(string, int);
        void printVertex();
    };

我已阅读了几篇有关此问题的主题(This one in particular) 但是当我尝试使用unique来对我的矢量进行排序时,我收到了一个非常奇怪的错误。

我使用push_back添加到矢量:

vector<Graph::Vertex> v;
Graph::Vertex first(string1, count);
v.push_back(first);

并尝试使用我在另一个线程中找到的代码进行排序:

void removeDup(vector<Graph::Vertex> v)
{
    sort( v.begin(), v.end());
    v.erase( unique( v.begin(), v.end() ), v.end() );
}

但是,当我使用此功能时,出现错误:

error C2678: binary '==' : no operator found which takes a left-hand operand of type 'Graph::Vertex' (or there is no acceptable conversion)

我对使用C ++进行编程并不熟悉,并且不知道为什么会出现这种错误,或者它意味着什么。有人可以解释为什么我收到此错误?我是否需要编写一个运算符重载函数来处理它?<​​/ p>

非常努力谷歌(并使用这个网站)解决这个错误,但最后不得不在这里发表我的第一篇文章寻求帮助。抬头:这是一个家庭作业,所以我决定不包括我的其余代码,以避免被勺子喂答案,但如果我没有给出足够的信息,请告诉我。

4 个答案:

答案 0 :(得分:0)

  • 编译器在需要排序时,不知道哪个Vertex放在另一个Vertex之前。您需要告诉编译器这些信息。因此,请使用3参数std::sort()函数,或为Vertex类编写重载operator <

  • 编译器不知道是什么让Vertex等于另一个Vertex。您需要告诉编译器这些信息。因此,请使用3参数std::unique()函数,或为Vertex类编写重载operator ==

  • 通过引用传递诸如vector之类的对象,而不是通过值传递:

    void removeDup(vector<Graph::Vertex>& v)

请注意&

答案 1 :(得分:0)

两个识别唯一对象,你需要能够测试相等性(毕竟,你如何识别相同的对象)。

假设有两个对象ab。测试平等的规范方法是a == b。如果你在int上运行,编译器就知道如何处理这个表达式(例如发出CMP指令)。

但是,由于您自己定义了Vertex,因此必须告诉编译器如何将两个Verteces视为相等。定义算术运算符的最简单方法是这样的:

struct Vertex
{
    string name;
    int num;
public:
    Vertex();
    Vertex(string, int);
    void printVertex();

    friend bool operator==(Vertex const& lhs, Vertex const& rhs)
    { return lhs.num == rhs.num; } // or whatever you wish to do here
};

提醒:在定义==时,您可能还希望将!=定义为一致。您也可以定义所有<<=>>=,以便进行比较......

答案 2 :(得分:0)

std::sortstd::unique都需要比较项目才能完成工作。但它们有一些不同的要求:std::unique比较等式和std::sort比较排序。您的案例的一个显而易见的可能性是这个一般订单上的代码:

bool operator==(Vertex const &other) const {
    return num == other.num;
}

bool operator<(Vertex const &other) const {
    return num < other.num;
}

[注意:这些将是您Vertex类的成员函数。]

可以通过其他方式实现所需的功能,特别是如果(例如)您可能希望有时基于一个字段对对象进行排序,而在其他时间对另一个字段进行排序(例如,按数字排序和对于Vertex类,按名称排序。)

您可以通过将第三个参数传递给sort和/或unique来告诉它使用什么来进行比较。至少在当前的C ++中,如果我要这样做,我通常使用lambda表达式来指定比较:

std::sort(v.begin(), v.end(),
    [](Vertex const &a, Vertex const &b) { return a.name < b.name; });

这会将比较代码放在排序旁边,因此很容易看出您是如何进行排序的。您可以使用单独的函数或函数对象,但这样做意味着您需要注意名称以确保它描述排序顺序:

struct by_name {
    bool operator()(Vertex const &a, Vertex const &b) const {
        return a.name < b.name;
    }
};

// ...
std:sort(v.begin(), v.end(), by_name());

答案 3 :(得分:0)

编译器在尝试排序时不知道如何将一个顶点对象与另一个顶点对象进行比较。你可以通过重载&lt; Vertex类中的运算符。此运算符将用于比较两个顶点并将其放置在另一个顶点之间。并且你需要重载operator ==以使用unique,因为它将使用operator ==来检查一个顶点是否与另一个顶点相等,从而找到重复。