Sort the vector of Class Entities in C++

I wanted to store the class entities in a vector and sort them based on my custom comparator functionality. There are multiple ways to sort the vector of class entities, but we will be discussing the most used three methods.

  1. Default operator<
  2. Comparator Function 
  3. LAMBDA 

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

struct Army		
{
private:
  int numberSuffix;
  int armyCode;
protected:
    string name;
public:
    Army (int armycode, int suffix): 
         armyCode(armycode), numberSuffix(suffix), name ("Shirley")
  {
    cout << "Super Class:: " << __func__ << endl;
  }

  int getArmyCode ()
  {
    return armyCode;
  }
};


int
main ()
{
  vector < Army > listOfArmy;
  Army *a1 = new Army (23, 11);
  //cout << "The officer's Name is " << a1->getArmyCode () << endl << endl;

  Army *a2 = new Army (2, 1);
  //cout << "The 2nd officer's Name is " << a2->getArmyCode () << endl << endl;

  listOfArmy.push_back (*a1);
  listOfArmy.push_back (*a2);

  vector < Army >::iterator it;
  cout << "Class Entity is stored as vector: " << endl;
  for (it = listOfArmy.begin (); it != listOfArmy.end (); ++it)
    {
      cout << it->getArmyCode() << endl;
    }
   
   sort(listOfArmy.begin(), listOfArmy.end());
   

  return 0;
}

Output 

error: no match for 'operator<' in '((__gnu_cxx::_LessThanComparableConcept<Army>*)this)->
__gnu_cxx::_LessThanComparableConcept<Army>::__a < ((__gnu_cxx::_LessThanComparable
Concept<Army>*)this)->__gnu_cxx::_LessThanComparableConcept<Army>::__b'
compilation terminated due to -Wfatal-errors.


We didn't specify in what basis we need to sort the Army class. If the type is int, it has the default comparator function for sort function. 

As the default operator< definition was missing, it threw those errors.

#include <iostream>
#include <algorithm>
#include <vector>
#include <tuple>
using namespace std;

struct Army
{
private:
  int numberSuffix;
  int armyCode;
protected:
    string name;
public:
    Army (int armycode, int suffix):armyCode (armycode),
    numberSuffix (suffix), name ("Shirley") {}

  int getArmyCode () const
  {
    return armyCode;
  }

  int getNumberSuffix () const
  {
    return numberSuffix;
  }


  //Method 1: of sorting default comparator function
  bool operator< (const Army & other)
  {
    cout << " Using default Operator< as comparator " << endl;
    //return (getArmyCode() < other.getArmyCode());

    /* This would first check if the armyCode is less
     * then secondly would check numberSuffix, and later
     * the name. */
    return std::tie (armyCode, numberSuffix, name)
      < std::tie (other.armyCode, other.numberSuffix, other.name);
  }


};

//Method 2: of Sorting comparator function
bool
sortArmy (const Army & lhs, const Army & rhs)
{
  cout << " Using function as Comparator " << endl;
  return (lhs.getArmyCode () < rhs.getArmyCode ());
  //return std::tie(lhs.getArmyCode(), lhs.getNumberSuffix(), lhs.name)
// < std::tie(rhs.getArmyCode(), rhs.getNumberSuffix(), rhs.name);
} int main () { vector < Army > listOfArmy; Army *a1 = new Army (25, 11); //cout << "The officer's Name is " << a1->getArmyCode () << endl << endl; Army *a2 = new Army (23, 1); //cout << "The 2nd officer's Name is " << a2->getArmyCode () << endl << endl; listOfArmy.push_back (*a1); listOfArmy.push_back (*a2); vector < Army >::iterator it; cout << "Class Entities stored as vector: " << endl; for (it = listOfArmy.begin (); it != listOfArmy.end (); ++it) { cout << it->getArmyCode () << " " << it->getNumberSuffix () << endl; } cout << "After sorting the vectors: " << endl; // sort(listOfArmy.begin(), listOfArmy.end()); // Method 1: Default operator< //sort(listOfArmy.begin(), listOfArmy.end(), sortArmy); // Method 2: Using comparator function sort (listOfArmy.begin (), listOfArmy.end (), [](const Army & lhs, const Army & rhs) { return (lhs.getArmyCode () < rhs.getArmyCode ()); }); // Method 3: LAMBDA expression for (it = listOfArmy.begin (); it != listOfArmy.end (); ++it) { cout << it->getArmyCode () << " " << it->getNumberSuffix () << endl; } return 0; }

Output 

Class Entities stored as vector: 
25  11
23  1
After sorting the vectors: 
23 1
25 11

Also, in the above program, unnecessarily, we allocated a pointer for each Army class which is not needed. 

#include <iostream>
#include <algorithm>
#include <vector>
#include <tuple>
using namespace std;

struct Army
{
private:
  int numberSuffix;
  int armyCode;
protected:
    string name;
public:
    Army (int armycode, int suffix):armyCode (armycode),
    numberSuffix (suffix), name ("Shirley") {}

  int getArmyCode () const
  {
    return armyCode;
  }

  int getNumberSuffix () const
  {
    return numberSuffix;
  }


  //Method 1: of sorting default comparator function
  bool operator< (const Army & other)
  {
    cout << " Using default Operator< as comparator " << endl;
    //return (getArmyCode() < other.getArmyCode());

    /* This would first check if the armyCode is less
     * then secondly would check numberSuffix, and later
     * the name. */
    return std::tie (armyCode, numberSuffix, name)
      < std::tie (other.armyCode, other.numberSuffix, other.name);
  }


};

//Method 2: of Sorting comparator function
bool
sortArmy (const Army & lhs, const Army & rhs)
{
  cout << " Using function as Comparator " << endl;
  return (lhs.getArmyCode () < rhs.getArmyCode ());
  //return std::tie(lhs.getArmyCode(), lhs.getNumberSuffix(), lhs.name)
  // < std::tie(rhs.getArmyCode(), rhs.getNumberSuffix(), rhs.name);
}


int
main ()
{
  vector < Army > listOfArmy;
  Army a1(25, 11);
  //cout << "The officer's Name is " << a1->getArmyCode () << endl << endl;

  Army a2(23, 1);
  //cout << "The 2nd officer's Name is " << a2->getArmyCode () << endl << endl;

  listOfArmy.push_back (a1);
  listOfArmy.push_back (a2);

  vector < Army >::iterator it;
  cout << "Class Entities stored as vector: " << endl;
  for (it = listOfArmy.begin (); it != listOfArmy.end (); ++it)
    {
      cout << it->getArmyCode () << "  " << it->getNumberSuffix () << endl;
    }

  cout << "After sorting the vectors: " << endl;
  // sort(listOfArmy.begin(), listOfArmy.end());   // Method 1: Default operator<
  //sort(listOfArmy.begin(), listOfArmy.end(), sortArmy);  // Method 2: Using comparator function 
  sort (listOfArmy.begin (), listOfArmy.end (),
	[](const Army & lhs, const Army & rhs)
	{
	return (lhs.getArmyCode () < rhs.getArmyCode ());
	});   // Method 3: LAMBDA expression

  for (it = listOfArmy.begin (); it != listOfArmy.end (); ++it)
    {
      cout << it->getArmyCode () << " " << it->getNumberSuffix () << endl;
    }

  return 0;
}

Output 

Class Entities stored as vector: 
25  11
23  1
After sorting the vectors: 
23 1
25 11

Click here for the above program.

References

https://www.cplusplus.com/reference/algorithm/sort/

https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11/7627330#7627330




Comments