Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does std::greater<> wоrk in a set?

Tags:

c++

c++14

I know how std::greater works. But when I read the API of std::greater since C++14 it has a default type of void. So, if we don't pass any template argument to greater it defaults to void as below. But the result is as expected in descending order.

#include <iostream>
#include <set>

template< class T = void >
struct greater;

int main()
{
    std::set<int, std::greater<>> s {4, 5, 6, 7}; // This transforms to std::set<int, std::greater<void>>
}

Can someone explain how this specialization works?

like image 712
Vegeta Avatar asked Dec 30 '22 15:12

Vegeta


1 Answers

It works by having the call operator be a function template instead of a function. Compare the old version to the new specialisation:

// greater<T>
bool operator()( const T& lhs, const T& rhs ) const;

// greater<void> i.e. greater<>
template< class T, class U>
auto operator()( T&& lhs, U&& rhs ) const;

What makes this great is the ability to compare objects of differing types.

This is crucial for example in case where given a string view, you need to look up whether an equivalent std::string is stored in a set. Being able to compare string view to a std::string allows us to not create a string from that string view. Which is good because std::string can potentially be expensive to create.

With the old comparator, it could only compare std::string to another std::string in which case we would have to create a std::string in order to look it up from a set of std::string.

like image 194
eerorika Avatar answered Jan 11 '23 19:01

eerorika