Многие темы о stackoverflow затронули эту тему, но я не могу понять это правильно для моего примера. У меня есть класс Event с временем, когда происходит событие. Я хочу отсортировать эти объекты в векторе по тому времени.

Сначала я начал реализовывать оператор <, но затем компилятор выдал следующую ошибку:

Ошибка 1 ошибка C2582: функция 'operator =' недоступна в 'Событии' c: \ program files (x86) \ microsoft visual studio 12.0 \ vc \ include \ algorithm 3009 1 sorting

Итак, я добавил оператор =

Ниже приведен код, который я использовал:

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

Когда я отлаживаю, я замечаю, что мои объекты вообще не отсортированы. Они находятся в том порядке, в котором я их добавил. Ниже приведен отрывок из переменной 'vector':

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

У меня следующие вопросы:

  1. Почему мои события не сортируются в векторе, когда я вызываю сортировку?
  2. Зачем сортировке нужен оператор =?
-2
luk 6 Авг 2014 в 13:22
1
operator= — оператор присваивания. Возможно, вы хотели operator==.
 – 
Mankarse
6 Авг 2014 в 13:25
Имена ваших аргументов в операторных функциях вводят в заблуждение, поскольку аргумент на самом деле является правой частью выражения.
 – 
Some programmer dude
6 Авг 2014 в 13:28
Возможный дубликат нестатического члена const, не может использовать значение по умолчанию оператор присваивания
 – 
MatthiasB
6 Авг 2014 в 13:31
Не создавайте константные члены в классах, вместо этого создавайте константные классы.
 – 
Neil Kirk
6 Авг 2014 в 13:32
: или просто сделайте его приватным с общедоступным геттером.
 – 
quantdev
6 Авг 2014 в 13:35

3 ответа

Лучший ответ

Проблема в том, что объекты вашего класса Event не могут быть назначены из-за члена const double time. Поскольку членом является const, его нельзя изменить, поэтому вы не можете использовать sort в контейнере с объектами Event, потому что для сортировки требуется присваивание.

Либо удалите const, либо переосмыслите то, что вы пытаетесь сделать. Кстати, вы сбиваете с толку оператор присваивания (operator=, это то, что sort требует ) with equality operator ( operator == `).

2
Wojtek Surowka 6 Авг 2014 в 13:29

Чтобы изменить порядок объектов внутри вектора, объект должен быть копируемым (или перемещаемым). Вы должны определить оператор = (который является присваиванием), имеющий форму:

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

Итак, ваша реализация оператора = неверна. Вы сравниваете два объекта, но это не то, что должен делать оператор = (присваивание!). Он должен назначить один объект (его содержимое) другому объекту и вернуть ссылку на назначенный объект. Имейте в виду, что вы также должны предоставить конструктор копирования, если вы реализуете оператор присваивания.

2
nh_ 6 Авг 2014 в 13:29
Класс не может быть скопирован/назначен из-за константного нестатического члена.
 – 
MatthiasB
6 Авг 2014 в 13:33
Я не узнал константу. Я думаю, что без устранения постоянства времени не будет возможности выполнить сортировку на месте.
 – 
nh_
6 Авг 2014 в 13:36

Это правильная реализация оператора настраиваемого присваивания для вопроса:

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

Также измените объявление оператора присваивания:

class Event{
public:
     Event& operator=(const Event&);
     // other declarations...
};
1
Ashis Kr. Das 25 Июн 2018 в 01:02