std::not2 is implemented in the following way:
template <class Predicate>
binary_negate<Predicate> not2 (const Predicate& pred)
{
return binary_negate<Predicate>(pred);
}
It uses std::binary_negate in its implementation and binary_negate which is inherited from std::binary_function requires _Predicate::first_argument_type and _Predicate::second_argument_type in its templated arguments in the following way:
template <class _Predicate>
class binary_negate : public binary_function<typename _Predicate::first_argument_type,
typename _Predicate::second_argument_type,
bool>
{
// ...
}
And my question is why I can write something like this if there are no typedefs for first_argument_type and second_argument_type in the Predicate that I am passing?
struct new_same
{
bool operator()(int a, int b) const { return a == b; }
};
auto not_same = std::not2(std::function<bool(int, int)>(new_same()));
There is also a (from cppreference):
template< class Predicate > (since C++11) struct binary_negate; (deprecated in C++17) (removed in C++20)
Further, std::function
does have the following typdefs:
first_argument_type (deprecated in C++17)(removed in C++20) second_argument_type (deprecated in C++17)(removed in C++20)
why I can write something like this if there are no typedefs for first_argument_type and second_argument_type in the Predicate that I am passing?
The typedefs are there. binary_negate
can get them from Predicate
(which is a std::function
in your case).
All this is deprecated in C++17
and removed in C++20
. I have to admit, that I cannot tell you what the replacement is.