Search code examples
c++templatesc++17typedef

Why std::function works as an argument to std::not2?


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()));

Solution

  • 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.