Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort objects with constant reference attributes in vector

Tags:

c++

I need some help with C++ vectors. I have an object which has two attributes, both constant references (this means that I don't have an empty constructor for the class). I need to create a vector with some of these objects and I need to sort them based on the value of one of the attributes (specifically the otherObj attribute, which class has all the operators overloaded).

I'm having some trouble because, when I try to do a simple std::sort on the vector, I think it tries to create another object of that class with an empty constructor to swap those objects, so I don't know what to do.

I paste an example code of how I basically have these objects (I may have made some errors)

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
}
like image 279
Fsanna Avatar asked Feb 03 '23 18:02

Fsanna


1 Answers

std::sort requires ValueSwappable of the iterators passed to it, and MoveAssignable and MoveConstructible of the pointed-to type.

By default that will call std::swap, which is approximately

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

I.e. it will modify the objects such that they have the values each other started with. Your objects can't be assigned to, so instantiating swap fails.

You can std::list::sort objects that aren't assignable, so instead

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

}
like image 64
Caleth Avatar answered Feb 06 '23 10:02

Caleth