-2

Many topics on stackoverflow have tackled this subject, but I can't manage to get it right for my example. I have a class Event with the time that the event takes place. I want to sort these objects in a vector according to that time.

I first started implementing the operator<, but then the compiler gave the following error:

Error 1 error C2582: 'operator =' function is unavailable in 'Event' c:\program files (x86)\microsoft visual studio 12.0\vc\include\algorithm 3009 1 sorting

So then I added the operator=

Below is the code I have used:

#include <algorithm>    // std::sort
#include <vector>       // std::vector

using namespace std;

class Event{
public:
     const double time;
     Event(double);
     bool operator<(const Event&);
     bool operator=(const Event&);
};

Event::Event(double time) :
time(time){

}

bool Event::operator<(const Event& rhs)
{
    return this->time < rhs.time;
}

bool Event::operator=(const Event& rhs)
{
    return this->time == rhs.time;
}

int main() {
    vector<Event> vector;
    Event e1 = Event(10);
    Event e2 = Event(5);
    Event e3 = Event(7);
    vector.push_back(e1);
    vector.push_back(e2);
    vector.push_back(e3);
    sort(vector.begin(), vector.end());
    return 0;
}

When I debug, I notice that my objects aren't sorted at all. They are in the order I added them. Below is an excerpt of the 'vector' variable:

[0] {time=10.000000000000000 }  Event
[1] {time=5.0000000000000000 }  Event
[2] {time=7.0000000000000000 }  Event

I have the following questions:

  1. Why aren't my events sorted in the vector when I call sort?
  2. Why does sort need operator= ?
luk
  • 3
  • 4

3 Answers3

2

The problem is that objects of your class Event cannot be assigned because of const double time member. Since the member is const it cannot be modified, so you cannot use sort on a container with Event objects, because sorting requires assignment.

Either remove const or rethink what you try to do. BTW you are confusing assignment operator (operator=, this is what sort requires) with equality operator (operator==`).

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
2

To reorder the objects inside the vector the object has to be copyable (or moveable). You have to define an operator= (which is an assignment) that is of the form:

Event& operator=(const Event& other) 
{
    if(&other != this) { this->time = other.time; }
    return *this;
}

So your implementation of operator= is wrong. You are comparing the two objects but this is not what operator= (assignment!) is supposed to do. It has to assign one object (its content) to another object and return a reference to the object assigned to. Keep in mind that you should provide a copy constructor as well if you implement an assignment operator.

nh_
  • 2,211
  • 14
  • 24
  • The class cannot be copied/assigned due to a const non-static member. – MatthiasB Aug 06 '14 at 09:33
  • I did not recognize the const. I think without removing the constness of time there will be no way for doing an inplace sort. – nh_ Aug 06 '14 at 09:36
1

This is the correct implementation of the custom assignment operator for the question:

Event& Event::operator=(const Event& other) 
{
    if(&other != this) {
        // As time is const, we modify it through a secondary reference
        // you can say it cheating with the compiler
        double &rTime = (double&) this->time;
        rTime = other.time;      // this modifies this->time variable
    }
    return *this;
}

Also, change the declaration of the assignment operator as well:

class Event{
public:
     Event& operator=(const Event&);
     // other declarations...
};