Сортировка объектов с постоянными эталонными атрибутами в векторе

Мне нужна помощь с векторами C++. У меня есть объект с двумя атрибутами, обе константные ссылки (это означает, что у меня нет пустого конструктора для класса). Мне нужно создать вектор с некоторыми из этих объектов, и мне нужно отсортировать их на основе значения одного из атрибутов (в частности, атрибута otherObj, в классе которого все операторы перегружены).

У меня возникли проблемы, потому что, когда я пытаюсь выполнить простую std::sort для вектора, я думаю, что он пытается создать другой объект этого класса с пустым конструктором для замены этих объектов, поэтому я не знаю, что сделать.

Я вставляю пример кода того, как у меня в основном есть эти объекты (возможно, я сделал некоторые ошибки)

class Object{
  const OtherObject& otherObj;
  const int& myInt;

  Object(const OtherObject& o, const int& i){
    this->otherObj = o;
    this->myInt = i;
  }

};

void myFunction(std::vector<OtherObject>& vec){
  int i1 = 1;
  int i2 = 2;
  int i3 = 3;

  Object obj1(vec.at(0), i1);
  Object obj2(vec.at(1), i2);
  Object obj3(vec.at(2), i3);

  std::vector<Object> myVec {obj1, obj2, obj3};

  //Sort the vector here
}

Может не актуально, но что такое OtherObject?

doctorlove 22.05.2019 10:48

Это может быть тривиально, но не забыли ли вы перегрузить operator< в 'Object' для работы std::sort или используете собственную функцию сортировки?

nada 22.05.2019 10:50

@doctorlove это объект, в котором я перегрузил почти все операторы, сортировка должна выполняться на основе этих OtherObjects в порядке возрастания. добавлю в вопрос

Sosnos 22.05.2019 10:51

Вы не можете повторно разместить ссылки, и std::sort попытается поменять местами (или переместить) ваш объект. Как вы ожидаете, что этот обмен будет работать? (Как правило, вам следует избегать ссылочных членов; см., например, stackoverflow.com/a/892303/147845 и isocpp.github.io/CppCoreGuidelines/…)

You 22.05.2019 10:53

вы уверены, что ваш объект должен сохранять использованная литература?

bruno 22.05.2019 10:54

@nada Я пробовал оба, последний с простым std::iter_swap, и это тоже не работает (может быть, я делаю какие-то ошибки)

Sosnos 22.05.2019 10:54

@Sosnos Нам нужно увидеть соответствующий код, чтобы проверить, есть ли ошибки.

nada 22.05.2019 10:55

@ Вот почему я спрашиваю, как это сделать, не меняя объекты местами, мне нужно найти способ их сортировки без std::sort

Sosnos 22.05.2019 10:56

@Sosnos Я вижу, вам, вероятно, следует уточнить это в своем вопросе.

nada 22.05.2019 10:57

@Sosnos запоминать ссылки, как вы, очень опасно, вы уверены, что хотите это сделать? ссылочные элементы так легко исчезают

bruno 22.05.2019 11:00

@bruno да, мне нужно использовать память как можно меньше, и мне сказали не использовать указатели, когда это не является строго необходимым

Sosnos 22.05.2019 11:00

@Sosnos: Сортировка обязательно приведет к перемещению объектов. Это ни в коем случае не тривиально для ссылочных членов. Вам действительно нужны справочные члены? Вы читали эти две ссылки, которые в основном говорят, что «референтные члены почти всегда ошибаются»?

You 22.05.2019 11:01

@Sosnos, если цель состоит в том, чтобы просто сохранить память, если вы используете 64b, как правило, размер инт равен 32b, а размер int& равен 64b, поэтому вы используете память потерянный (избегайте опасности действовать так, как вы, ваш код фабрика неопределенного поведения ;-))

bruno 22.05.2019 11:01

@ Да, да, я их читал, в основном мне нужно избавиться от этих ссылок, но как я могу избежать копирования объектов?

Sosnos 22.05.2019 11:07

@bruno хорошо, что я не знал, я изменю это, спасибо!

Sosnos 22.05.2019 11:08

Обратите внимание, что ваш конструктор имеет неопределенное поведение, поскольку вы назначаете неинициализированные ссылки. Вы должны инициализировать ссылки в списке инициализаторов.

molbdnilo 22.05.2019 12:57
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
9
16
386
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

std::sort требует ValueSwappable переданных ему итераторов, а также MoveAssignable и MoveConstructible типа, на который указывает.

По умолчанию это вызовет std::swap, что примерно

template< class T >
void swap( T& a, T& b )
{
    T temp = std::move(a);
    a = std::move(b);
    b = std::move(temp);
}

т.е. это будет изменить объектов, с которых они начинают друг друга с значения. Ваши объекты не могут быть назначены, поэтому создание экземпляра swap не удается.

Вы могуstd::list::sort объекты, которые нельзя назначать, поэтому вместо этого

void myFunction(std::vector<OtherObject>& vec){
  int i1 = 1;
  int i2 = 2;
  int i3 = 3;

  Object obj1(vec.at(0), i1);
  Object obj2(vec.at(1), i2);
  Object obj3(vec.at(2), i3);

  std::list<Object> myList{obj1, obj2, obj3};
  myList.sort();
  std::vector<Object> myVec{ myList.begin(), myList.end() };

}

Другие вопросы по теме