The usefulness of unary and binary negators is easily understandable.
Example with unary negator (not1):
class Even
{
public:
bool operator() (const int& x) const { return x % 2 == 0; }
typedef int argument_type;
};
int values[] = { 9, 1, 8, 2, 7, 3, 6, 4, 5 };
int even = count_if(values, values + 9, Even());
int odd = count_if(values, values + 9, not1(Even())); // <= unary negator
cout << "We have " << even << " even elements in the array.\n";
cout << "We have " << odd << " odd elements in the array.\n";
Output:
We have 4 even elements in the array.
We have 5 odd elements in the array.
Example with binary negator (not2):
int values[] = { 9, 1, 8, 2, 7, 3, 6, 4, 5 };
// original array
for (int i : values)
cout << i << " ";
cout << "\n";
// array in ascending order
sort(values, values + 9, less<int>());
for (int i : values)
cout << i << " ";
cout << "\n";
// array in descending order
sort(values, values + 9, not2(less<int>())); // <= binary negator
for (int i : values)
cout << i << " ";
cout << "\n\n";
Output:
9 1 8 2 7 3 6 4 5
1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1
What about n-ary negators (not3, not4, not5 ... notn) ?
Let's assume that I need to count the number of elements that are not between two numbers (lower bound limit and upper bound limit) in a collection (maybe an array).
.
int elems_betweem = count_if(values, values + n, not3(bind(Between<int>(), _1, lowerValue, upperValue)));
.
How do I write the not3 negator?
Even more, do we have a generic not
as a replacer of not1
and not2
in the same way as bind
vs bind1st
and bind2nd
?
Thank you
Since C++17 std::not_fn will be available:
auto between = [](int value, int lowerValue, int upperValue) {
return lowerValue < value && value < upperValue;
};
int elems_between = std::count_if(std::cbegin(values), std::cend(values),
std::bind(std::not_fn(between), std::placeholders::_1, lowerValue, upperValue));