std::bind do not work with std::sort

why it works only if the second argument is greater than 3. And how can I fix it? if I do the same with copy_if it works! Task: Examine the effect of the functor std :: bind. Try using it to form the conditions of the standard functor std :: greater ( module).

#include <set>
#include <algorithm>
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <iterator>
#include <string>
#include <functional>
using namespace std;

template<typename T>
static void PrintVector(const std::vector<T> &v)
{
    for (auto iterator = v.begin(); iterator != v.end(); ++iterator)
    {
        std::cout << *iterator << " ";
    }
    std::cout << std::endl;
}

int main()
{
    std::cout << "Task_3: greater with std::bind\n";
    ostream_iterator<int> out_it(cout, " ");
    vector<int> v = { 1, 8, 7, 4, 3, 6, 2, 5 };
    PrintVector(v);
    auto greater_binded = bind(greater<int>(), placeholders::_1, 3);
    sort(v.begin(), v.end(), greater_binded);
    PrintVector(v);
    return 0;
}

Upvotes: 1

Views: 948

Answers (2)

Jonathan Mee
Jonathan Mee

Reputation: 38919

sort's comparator requirement is:

Comparison function object (i.e. an object that satisfies the requirements of Compare) which returns ​true if the first argument is less than (i.e. is ordered before) the second

The greater functor takes 2 arguments, but you are using bind to make it into a functor that takes 1 argument and compares it to 3. This no longer satisfies sort's requirement.

If you're trying to move all the elements that are greater than 3 to the front of v you could use partition with greater_binded. Calling partition(begin(v), end(v), greater_binded) results in:

5 8 7 4 6 3 2 1

You could also go further using the return of partition which is an:

Iterator to the first element of the second group

Using that to sort or reverse-sort the 1st or 2nd groups with sort.

Upvotes: 0

Slava
Slava

Reputation: 44258

As stated in documentation for std::copy_if it expects unary predicate ie function with one argument, on another side std::sort needs compare function, that must meet requirement of Compare concept. So is is completely unclear why you expect the same function used for std::copy_if work with std::sort.

And how can I fix it?

Just pass std::greater<int> without binding second argument to constant. If you do need to use std::bind you can just pass both arguments:

auto greater_binded = bind(greater<int>(), placeholders::_1, placeholders::_2);

but that would have the same effect as passing greater<int>() directly.

Upvotes: 1

Related Questions