1

In a template function a std::vector shall get sorted. T can be a simple type or a std::pair e.g.,

std::vector<double> or 
std::vector<std::pair<int,Something> >

When T is a pair then only the first element shall be compared. How can I implement the comparator for the two cases?

I have tried:

template<typename T>
inline bool smaller(const T& a,const T& b)
{
    return a<b;
}

template<typename T,typename S>
inline bool smaller(
    const std::pair<T,S>& a,
    const std::pair<T,S>& b
    )
{
    return a.first<b.first;
}

template<typename T> inline void function(std::vector<T >& vVec)
{
...bla...
sort(vVec.begin(),vVec.end(),smaller<T>);
...bla...
}

but it does not work this way. I have also tried specialization but I do not find the right syntax to specialize the smaller() function.

Raffi
  • 107
  • 1
  • 8
  • Did you try `sort(vVec)` simply? – Damien May 28 '19 at 15:25
  • Related: https://stackoverflow.com/questions/4610232/sorting-a-stdvectorstdpairstdstring-bool-by-the-string – Damien May 28 '19 at 15:26
  • @Damien, sort(vVec.begin(),vVec.end()) would also compare the second element of the pair. This is not necessary in the application and it would require an operator< for the second element. – Raffi May 28 '19 at 15:55
  • The fact that it is not necessary does not mean that it would be a problem, at the condition of course that the operator `<` is defined for the second element as you mentioned. – Damien May 28 '19 at 16:04

2 Answers2

3

You could just wrap it in a lambda:

std::sort(vVec.begin(),vVec.end(), [](const auto& a, const auto& b) { return smaller(a, b); });
Artyer
  • 31,034
  • 3
  • 47
  • 75
3

One easy work around is to make both of your smaller functions opeator()'s of a smaller struct. Using

struct smaller
{
    template<typename T>
    bool operator()(const T& a,const T& b)
    {
        return a < b;
    }

    template<typename T, typename S>
    bool operator() (const std::pair<T, S>& a, const std::pair<T, S>& b)
    {
        return a.first < b.first;
    }
};

allows you to just pass a smaller to sort like

template<typename T> inline void function(std::vector<T >& vVec)
{
    sort(vVec.begin(),vVec.end(),smaller{});
}

and in sort overload resolution will kick in on the two operator() smaller has and for any std::vector<std::pair>, the std::pair overload will be called.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402