malloy
malloy

Reputation: 23

How to sort a list of instances of a C++ class

I'm writing a C++ program for a 2D RPG game, using the SDL2 libraries. I have a class named Entity that has a property named worldY:

class Entity 
{
public:
        ...
    // coordinate mondo: la mappa del mondo
    int worldX = 0, worldY = 0;
}

In another class GamePanel I declare one of its properties:

std::list<Entity> entityList;
std::vector<Entity> npc;

The NPC vector is filled with instances of the:

class NPC_OldMan : public Entity

in this way:

for (int i = 0; i < npc.size(); i++)
{
    if (!npc.at(i).name.empty())
    {
        entityList.push_back(npc.at(i));
    }
}

Now I would like the entityList to be sorted in ascending order by the worldY property. i.e. if npc1 has worldY = 10 and npc2 has worldY = 5, then in the entityList I want to have npc2 and then npc1. Using the following includes:

#include <algorithm>
#include <iostream>
#include <list>
#include <iterator>

I was thinking of using this:

std::sort(entityList.begin(), entityList.end(), [](Entity e1, Entity e2) 
    {
    // Custom comparison logic 
    return e1.worldY < e2.worldY; // this sorts in ascending order 
    });

But I can't compile it, because it gives me this error:

Severity Code Description Project File Line Suppression State Details Error C2676 binary '-': 'const std::_List_unchecked_iterator<std::_List_val<std::_List_simple_types<_Ty>>>' does not define this operator or a conversion to a type acceptable to the predefined operator with [ _Ty=Entity ] My2DGame_21 C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.40.33807\include\algorithm 8165

I also tried to do this, but the result doesn't change, I always get the same error:

std::sort(entityList.begin(), entityList.end(), [](const auto& a, const auto& b) { return a.worldY < b.worldY; });

How should I fix my code? I do not know how to do. Is there another way to do this sorting of the list ?

Upvotes: 0

Views: 162

Answers (4)

You can use std::list::sort:

entityList.sort([](const auto& a, const auto& b) { return a.worldY < b.worldY; })

or just use std::vector to use std::sort.

Upvotes: 1

malloy
malloy

Reputation: 23

I found the solution that I report here with an example similar to mine:

#include <algorithm> 
#include <iostream> 
#include <vector> 
using namespace std; 
  
// creating a custom class 
class MyClass { 
public: 
    int data; 
  
    MyClass(int a) 
        : data(a) 
    { 
    } 
  
    // Overloading < operator 
    bool operator<(const MyClass& obj) const
    { 
        return data < obj.data; 
    } 
}; 
  
int main() 
{ 
    // Vector of custom objects 
    vector<MyClass> vec; 
    vec.push_back(MyClass(30)); 
    vec.push_back(MyClass(10)); 
    vec.push_back(MyClass(20)); 
    vec.push_back(MyClass(40)); 
  
    // Sorting the vector of custom objects 
    sort(vec.begin(), vec.end()); 
  
    // Printing  the vector 
    cout << "Sorted vector: "; 
    for (auto& obj : vec) 
        cout << obj.data << " "; 
    cout << endl; 
  
    return 0; 
}

Upvotes: 0

Eugene
Eugene

Reputation: 7688

You can sort std::list using its member function sort():

entityList.sort([](const auto& a, const auto& b) { return a.worldY < b.worldY; });

However, if you don't have a special reason to use std::list, use std::vector instead. In this case, the source code you showed will work.

Upvotes: 6

Dmitry Gordon
Dmitry Gordon

Reputation: 2324

You can't do that with std::list. std::sort requires a pair of random access iterator and std::list is obviously not the case.

Most probably you need to use std::vector instead.

Upvotes: 1

Related Questions