Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I pass a parameter to an std::vector sort function?

Consider the class:

MyClass {
    int varA;
    int varB;
};

I have a vector of pointers to MyClass objects:

std::vector<MyClass*> Vec;

I want to sort the vector according to varA or varB using the same sort function, i.e. :

bool SortFunction(const MyClass* obj1, const MyClass* obj2, const short type) {
     if( type == VARA_ID )
         return obj1->varA < obj2->varA;
     else if( type == VARB_ID )
         return obj1->varB < obj2->varB;
}

AFAICT this is not possible. What would be the most elegant way to this without using external libraries?

like image 949
Paulo Pinto Avatar asked Jan 28 '10 15:01

Paulo Pinto


People also ask

Can we use sort function in vector?

A vector in C++ can be easily sorted in ascending order using the sort() function defined in the algorithm header file. The sort() function sorts a given data structure and does not return anything.

How do you pass a function to sort in C++?

sort() takes a third parameter that is used to specify the order in which elements are to be sorted. We can pass the “greater()” function to sort in descending order. This function does a comparison in a way that puts greater elements before.

How do you sort a vector without using the sort function?

The vector can use the array notation to access the elements. If you don't want to use the default std::sort , or std::sort with custom comparator, you can use qsort or write your own.

What sort does std::sort use?

The std::sort is a sorting function that uses the Introsort algorithm and have the complexity of O(N log(N)) where N= std::distance(first, last) since C++11 and the order of equal elements is not guaranteed to be preserved[3]. The gcc-libstdc++ also uses Introsort algorithm.


2 Answers

class sorter {
      short type_;
public:
      sorter(short type) : type_(type) {}
      bool operator()(MyClass const* o1, MyClass const* o2) const {
            return SortFunction(o1, o2, type_ );
      }
};

std::sort(Vec.begin(), Vec.end(), sorter(MY_TYPE) );
like image 65
OwnWaterloo Avatar answered Sep 20 '22 14:09

OwnWaterloo


You're almost there, make type a template parameter and the signature is OK:

template<int type>
bool SortFunction(const MyClass* obj1, const MyClass* obj2) {
     if( type == VARA_ID )
         return obj1->varA < obj2->varA;
     else // if( type == VARB_ID ) -- A sort function must have a default.
         return obj1->varB < obj2->varB;
}

std::sort(Vec.begin(), Vec.end(), &SortFunction<VARA_ID> );

The optimizer will spot that ( type == VARA_ID ) is a compile-time constant.

like image 23
MSalters Avatar answered Sep 19 '22 14:09

MSalters