Почему код не работает, если вместо 3 вставить число меньше 6. И как это можно исправить? Код должен сортировать вектор с помощью функтора std::greater, который должен применять 1 параметр. Сделать это нужно с помощью std::bind.
#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()
{
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;
}
Алгоритм std::sort предполагает наличие strict weak ordering для функций сравнения (25.4 Sorting and related operations)
3 For all algorithms that take Compare, there is a version that uses operator< instead. That is, comp(*i, *j) != false defaults to *i < *j != false. For algorithms other than those described in 25.4.3 to work correctly, comp has to induce a strict weak ordering on the values.
Это значит, что не допускается, что если comp( a, b ) есть true, то одновременно и comp( b, a ) также true.
Если вы хотите разбить массив на партиции, то используйте стандартный алгоритм std::partition. Например,
std::partition( v.begin(), v.end(), greater_binded );
Если необходимо, то затем каждую партицию можно отсортировать отдельно.
А что этот код должен делать? std::sort принимает бинарный предикат. Что-то с чем можно сделать так:
if(pred(x, y)){
//...
}
Вы же взяли бинарный предикат greater и забиндили у него один аргумент. По идее теперь он принимает только один аргумент. Хотя на самом деле не специфицировано что там возвращает std::bind(пример)
Короче, код хоть и компилируется, но работать в таком виде правильно не будет. Потому что предикат greater_binded работает только с одним аргументом, а для сортировки нужно сравнивать два элемента.
В этом легко убедится, если заменить std::bind на старый добрый std::bind2nd. Ошибка выполнения сразу превратится в ошибку компиляции:
#include <algorithm>
#include <iostream>
#include <vector>
#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()
{
vector<int> v = { 1, 8, 7, 4, 3, 6, 2, 5 };
PrintVector(v);
auto greater_binded = bind2nd(greater<int>(), 3);
sort(v.begin(), v.end(), greater_binded);
PrintVector(v);
}
h:125:23: error: no matching function for call to object of type 'std::binder2nd >' { return bool(_M_comp(*__it1, *__it2)); }
Сборка персонального компьютера от Artline: умный выбор для современных пользователей