简体   繁体   English

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

[英]C++ trouble sorting a vector of custom objects

Edit, Update: Great answers thank you all. 编辑,更新:好的答案谢谢大家。 I've written operator overloading for < and == operators. 我为<和==运算符编写了运算符重载。 I am no longer receiving the error. 我不再收到错误。 I also correctly passed the vector by reference instead of by value into my removeDup(vector<Graph::Vertex>&); 我还正确地通过引用而不是值将向量传递给我的removeDup(vector<Graph::Vertex>&); function. 功能。

I have a vector of objects that I need to remove duplicates from, but I am receiving an error that I am unfamiliar with (the error is below). 我有一个需要从中删除重复项的对象向量,但是我收到一个我不熟悉的错误(错误在下面)。 It's a very simple object publicly contained within a class called Graph : 这是一个非常简单的对象,公开包含在名为Graph的类中:

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

I have read through a few threads regarding this ( This one in particular ) but I am getting a very strange error when I try to sort my vector using unique. 我已经通读了一些与此相关的主题( 特别是本主题),但是当我尝试使用unique对向量进行排序时,我遇到了一个非常奇怪的错误。

I add to the vector using push_back : 我使用push_back添加到向量:

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

and attempt to sort using this code that I found in another thread: 并尝试使用在另一个线程中找到的以下代码进行排序:

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

However, when I use this function, I get an error: 但是,当我使用此功能时,出现错误:

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

I am slightly new to programming in C++ and have no idea why this error is happening, or what it means. 我刚开始使用C ++编程,不知道为什么会发生此错误或其含义。 Could someone explain why I am getting this error? 有人可以解释为什么我收到此错误吗? Do I need to write an operator overload function to take care of it? 我需要编写一个运算符重载函数来处理它吗?

Tried very hard to google (and use this website) for the solution to this error, but in the end had to make my first post here for help. 试图用谷歌搜索(并使用此网站)来解决此错误,但是最终不得不在这里发表我的第一篇文章以寻求帮助。 A heads up: this is for a homework assignment, so I decided not to include the rest of my code to avoid being spoon fed the answers, but if I haven't given enough information, please let me know. 请注意:这是一项家庭作业,因此我决定不包括代码的其余部分,以免被别人误以为是答案,但是如果我没有提供足够的信息,请告诉我。

  • The compiler has no idea which Vertex is placed before another Vertex when it needs to be sorted. 当需要对其进行排序时,编译器不知道哪个顶点位于另一个顶点之前。 You need to tell the compiler this information. 您需要告诉编译器此信息。 Therefore use the 3 argument std::sort() function, or write an overloaded operator < for your Vertex class. 因此,请使用3个参数std::sort()函数,或为您的Vertex类编写一个重载的operator <

  • The compiler has no idea what makes a Vertex equal to another Vertex. 编译器不知道是什么使一个顶点等于另一个顶点。 You need to tell the compiler this information. 您需要告诉编译器此信息。 Therefore use the 3 argument std::unique() function, or write an overloaded operator == for your Vertex class. 因此,请使用3个参数std::unique()函数,或为您的Vertex类编写一个重载的operator ==

  • Pass objects such as vector by reference, not by value: 通过引用而不是通过值传递矢量之类的对象:

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

Note the & . 注意&

Two recognize unique objects, you need to be able to test for equality (after all, how else would you recognize to objects that are the same). 两个识别唯一的对象,您需要能够测试是否相等(毕竟,对于相同的对象,您还将如何识别)。

Assume two objects a and b . 假设两个对象ab The canonical way to test for equality is a == b . 检验相等性的规范方法是a == b If you operate on int s the compiler knows how to deal with this expression (eg emit a CMP instruction). 如果您对int进行操作,则编译器会知道如何处理此表达式(例如,发出CMP指令)。

However, since you defined Vertex yourself, the compiler must be told how to consider two Verteces to be equal. 但是,由于您自己定义了Vertex ,因此必须告知编译器如何将两个Verteces视为相等。 The easiest way to define arithmetic operators is like this: 定义算术运算符的最简单方法是这样的:

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
};

Just a heads up: When defining == you may wish to also define != to be consistent. 请注意:定义==您可能还希望定义!=以便保持一致。 You also may wish to define all the < , <= , > , >= so that comparision is possible... 您还可能希望定义所有<<=>>=以便可以进行比较...

std::sort and std::unique both need to compare items to do their jobs. std::sortstd::unique都需要比较项目才能完成工作。 They have somewhat different requirements though: std::unique compares for equality and std::sort compares for ordering. 但是它们有一些不同的要求: std::unique比较是否相等, std::sort比较排序。 One obvious possibility for your case would be code on this general order: 对于您的情况,一种明显的可能性是按以下一般顺序执行代码:

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

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

[Note: these would be member functions of your Vertex class.] [注意:这些将是您的Vertex类的成员函数。]

It's possible to implement the required functionality in other ways, especially if (for example) you might want to sort objects based on one field sometimes, and by another field at other times (eg, sort by number and sort by name, in the case of your Vertex class). 可以用其他方式来实现所需的功能,尤其是(例如)如果您有时希望根据一个字段对对象进行排序,而有时又希望根据另一个字段对对象进行排序(例如,在这种情况下,按数字排序和按名称排序)您的Vertex类)。

You can do that by passing a third parameter to sort and/or unique to tell it what to use to do the comparison. 您可以通过传递第三个参数进行sort和/或unique来告诉它使用什么来进行比较来做到这一点。 At least in current C++, if I'm going to do this, I generally use a lambda expression to specify the comparison: 至少在当前的C ++中,如果要执行此操作,通常会使用lambda表达式来指定比较:

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

This puts the comparison code right next to the sort, so it's easy to see how you're doing the sorting. 这会将比较代码放在排序的旁边,因此很容易看到您如何进行排序。 You can use a separate function or function object instead, but doing so means you need to be careful with the name to ensure it describes the sort order: 您可以改用单独的函数或函数对象,但这意味着您需要谨慎使用名称,以确保它描述了排序顺序:

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());

The compiler does not know how to compare one vertex object with another when it tries to sort. 编译器在尝试排序时不知道如何将一个顶点对象与另一个顶点对象进行比较。 you can do it by overloading < operator in your Vertex class. 您可以通过在Vertex类中重载<运算符来实现。 This operator will be used to compare tow vertices and place one before another. 该运算符将用于比较两个顶点并将一个顶点放置在另一个顶点上。 and you need to overload operator == to be used in unique, since it will use operator == to check if one vertex is equal to another and hence find duplicates. 并且您需要重载运算符==以用于唯一,因为它将使用运算符==检查一个顶点是否等于另一个顶点,从而找到重复的顶点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM