C++ Custom Compare Function for Std::Sort()

c++ sorting with custom compare function

Lambdas:

std::sort(
neighbors.begin(),
neighbors.end(),
[index](const std::pair< std::pair< int, int >, std::vector<float> > &a,
const std::pair< std::pair< int, int >, std::vector<float> > &b)
{
return ( a.second[index] > b.second[index] );
}
);

See What is a lambda expression in C++11? for a detailled introduction.

c++ custom compare function for std::sort()

std::pair already has the required comparison operators, which perform lexicographical comparisons using both elements of each pair. To use this, you just have to provide the comparison operators for types for types K and V.

Also bear in mind that std::sort requires a strict weak ordeing comparison, and <= does not satisfy that. You would need, for example, a less-than comparison < for K and V. With that in place, all you need is

std::vector<pair<K,V>> items; 
std::sort(items.begin(), items.end());

If you really need to provide your own comparison function, then you need something along the lines of

template <typename K, typename V>
bool comparePairs(const std::pair<K,V>& lhs, const std::pair<K,V>& rhs)
{
return lhs.first < rhs.first;
}

std::sort with custom comparator

std::sort accepts a functor. This is any object that can be called (with the correct parameters). The function achieves this by using templates, like the following

template<typename Iter, typename Comp>
void sort(Iter begin, Iter end, Comp compare) { ... }

IntComparator1, 2, and 3 are all valid functors for this comparator, since they can all be called using operator() with 2 integers.

Also like you said, the third option is indeed usually more intuitive.

Custom comparison function for SORT in C++ STL?

Your comparison function doesn't define an ordering. In fact,
it seems to return true any time a.first != b.first.

I'm not sure what sort of custom order you want. The standard
ordering of std::pair will result in something like:

bool
comp( t const& a, t const& b )
{
if ( a.first != b.first )
return a.first < b.first;
else if ( a.second.first != b.second.first )
return a.second.first < b.second.first;
else
return a.second.second < b.second.second;
}

It's actually a bit more complicated, since the only comparison
operator it uses is <. But if < and != are both
available, and behave normally, the results are the same as the
above.

You can easily adopt this to compare the elements in whatever
order you want; if you want to inverse the order for one of the
elements, just replace < with >.

And finally, false compares less than true for boolean
values.

How to add a comparator to a custom sort function

Considering you have a class or struct CustomType

Pre c++11

struct CustomCompare
{
bool operator ()(const CustomType& a, const CustomType& b)
{
return a.Watever < b.Watever;
}
};

//usage
merge(vector<CustomType> ..., CustomCompare());

Post c++11, using lambdas:

auto CustomCompare = [](const CustomType & a,const CustomType& b)
{
return a. .... ;
};
//usage
merge(vector<CustomType> ..., CustomCompare);

There is third option:

You can use std::less but there must exist an operator < that takes your CustomType as arguments

Example:

struct CustomType
{
//...
bool operator < (const CustomType& other)const
{
return this->Whatever < other.Whatever;
}
};

And you can specialize std::less:

namespace std
{
template <>
struct less <CustomType>
{
bool operator()(const CustomType & a, const CustomType & b)
{
return ...
}
};
}


Related Topics



Leave a reply



Submit