Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Container version of C++ sort

Tags:

c++

c++11

vector

I was reading Stroustrup's blog on c++ (http://isocpp.org/blog/2014/12/myths-3) when I found an intersting piece of code:

void do_my_sort(vector<double>& v)
{
  sort(v,[](double x, double y) { return x>y; });  // sort v in decreasing order
}

int main()
{
  vector<double> vd;
  // ... fill vd ...
  do_my_sort(v);
  // ...
} 

Notice that the sort does not use the traditional sort(v.begin(), v.end(), ...) which Stroustrup explains:

I used a container version of sort() to avoid being explicit about the iterators.

However, I tried the same code on my C++11 compiler but it fails to compile. I also tried the same on a C++14 compiler using ideone but it too fails to compile, saying that there is no matching call to sort.

Why is this?

Also, Stroustrup next mentions:

I could go further and use a C++14 comparison object:

sort(v,greater<>()); // sort v in decreasing order

I have used comparators like great<>() for sort in C++11 also. Why is he stating that this is a C++14 comparison object?

like image 641
1110101001 Avatar asked Dec 06 '22 23:12

1110101001


2 Answers

He wrote that himself, it is not standard. Thus you cannot find it in the standard library. You could implement it like this:

template <class Container, class Comp>
void sort (Container& cont, Comp comp) {
    using std::begin;
    using std::end;
    std::sort(begin(cont), end(cont), comp);
}

As Clukester pointed out, there is also boost::sort that offers this functionality.

like image 199
Baum mit Augen Avatar answered Dec 28 '22 02:12

Baum mit Augen


I have used comparators like great<>() for sort in C++11 also. Why is he stating that this is a C++14 comparison object?

The C++14 comparison functors have the added ability to take forwarding references for its operator() method and deduced return types. The template argument for the Function Objects collection has been changed to have a default argument of type void and using specialization for that type.

template< class T = void >
struct greater
{
    constexpr bool operator()(const T &lhs, const T &rhs) const;
};

template<>
struct greater<void>
{
    template< class T, class U>
    constexpr auto operator()( T&& lhs, U&& rhs ) const
      -> decltype(std::forward<T>(lhs) > std::forward<U>(rhs));
};
like image 34
David G Avatar answered Dec 28 '22 02:12

David G