std::not2(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸŽ€ NAME πŸŽ€

std::not2 β€” literally std::not2, that's the whole name bestie πŸ’–


✨ SYNOPSIS ✨

Defined in header <functional> πŸ¦‹

template< class Predicate >                                    (until C++14)
std::binary_negate<Predicate> not2( const Predicate& pred );

template< class Predicate >                                    (since C++14)
constexpr std::binary_negate<Predicate> not2( const Predicate& pred );
(deprecated in C++17)
(removed in C++20)

🌸 DESCRIPTION 🌸

okay so picture this: std::not2 is a little helper function whose entire personality is creating a function object that returns the complement of the binary predicate function you hand it. Like, it flips your trues to falses and your falses to trues. The function object it creates is of type std::binary_negate<Predicate>. periodt πŸ’…

Here's the catch though, and it's kind of a big one β€” your binary predicate type must define two member types, first_argument_type and second_argument_type, and those have to be convertible to the predicate's parameter types. No exceptions, that's the vibe check πŸ‘‘

The function objects you get from all of these lovely things have those types defined for you already:

  • std::owner_less
  • std::ref
  • std::cref
  • std::plus
  • std::minus
  • std::multiplies
  • std::divides
  • std::modulus
  • std::equal_to
  • std::not_equal_to
  • std::greater
  • std::less
  • std::greater_equal
  • std::less_equal
  • std::logical_not
  • std::logical_or
  • std::bit_and
  • std::bit_or
  • std::bit_xor
  • std::mem_fn
  • std::map::value_comp
  • std::multimap::value_comp
  • std::function

…or from another call to std::not2, obviously. Same goes for function objects derived from the deprecated std::binary_function β€” they've got these types too 🫢


πŸ¦‹ PARAMETERS πŸ¦‹

  • pred β€” a binary predicate. that's it. that's the parameter πŸ“

⭐ RETURN VALUE ⭐

std::not2 returns an object of type std::binary_negate<Predicate>, constructed with pred. iconic behavior, no notes πŸ’œ


πŸ™ˆ EXCEPTIONS πŸ™ˆ

(none) β€” literally none, we love a low-drama function 😭


πŸ”₯ EXAMPLE πŸ”₯

Run this code, bestie, I promise it slaps:

#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
#include <vector>

struct old_same : std::binary_function<int, int, bool>
{
    bool operator()(int a, int b) const { return a == b; }
};

struct new_same
{
    bool operator()(int a, int b) const { return a == b; }
};

bool same_fn(int a, int b)
{
    return a == b;
}

int main()
{
    std::vector<int> v1{0, 1, 2};
    std::vector<int> v2{2, 1, 0};
    std::vector<bool> v3(v1.size());

    std::cout << "negating a binary_function:\n";
    std::transform(v1.begin(), v1.end(), v2.begin(), v3.begin(),
                   std::not2(old_same()));

    std::cout << std::boolalpha;
    for (std::size_t i = 0; i < v1.size(); ++i)
        std::cout << v1[i] << ' ' << v2[i] << ' ' << v3[i] << '\n';

    std::cout << "negating a standard functor:\n";
    std::transform(v1.begin(), v1.end(), v2.begin(), v3.begin(),
                   std::not2(std::equal_to<int>()));

    for (std::size_t i = 0; i < v1.size(); ++i)
        std::cout << v1[i] << ' ' << v2[i] << ' ' << v3[i] << '\n';

    std::cout << "negating a std::function:\n";
    std::transform(v1.begin(), v1.end(), v2.begin(), v3.begin(),
                   std::not2(std::function<bool(int, int)>(new_same())));

    for (std::size_t i = 0; i < v1.size(); ++i)
        std::cout << v1[i] << ' ' << v2[i] << ' ' << v3[i] << '\n';

    std::cout << "negating a std::reference_wrapper:\n";
    std::transform(v1.begin(), v1.end(), v2.begin(), v3.begin(),
                   std::not2(std::ref(same_fn)));

    for (std::size_t i = 0; i < v1.size(); ++i)
        std::cout << v1[i] << ' ' << v2[i] << ' ' << v3[i] << '\n';
}

🌈 Output

negating a binary_function:
0 2 true
1 1 false
2 0 true
negating a standard functor:
0 2 true
1 1 false
2 0 true
negating a std::function:
0 2 true
1 1 false
2 0 true
negating a std::reference_wrapper:
0 2 true
1 1 false
2 0 true

look at that consistency, she ate and left no crumbs πŸ‘‘βœ¨


πŸ’€ SEE ALSO πŸ’€

  • not_fn (C++17) β€” creates a function object that returns the complement of the result of the function object it holds (function template)
  • binary_negate (deprecated in C++17) (removed in C++20) β€” wrapper function object returning the complement of the binary predicate it holds (class template)
  • function (C++11) β€” wraps callable object of any copy constructible type with specified function call signature (class template)
  • move_only_function (C++23) β€” wraps callable object of any type with specified function call signature (class template)
  • not1 (deprecated in C++17) (removed in C++20) β€” constructs custom std::unary_negate object (function template)
  • ptr_fun (deprecated in C++11) (removed in C++17) β€” creates an adaptor-compatible function object wrapper from a pointer to function (function template)
  • binary_function (deprecated in C++11) (removed in C++17) β€” adaptor-compatible binary function base class (class template)

⚠️ heads up babe: std::not2 is deprecated in C++17 and straight up removed in C++20. if you're on a modern compiler, please don't come crying to me β€” go look at not_fn instead πŸ’…

okay that's the whole page, mwah πŸ’– this masterpiece came from http://cppreference.com, dated 2024.06.10, and it's filed under std::not2(3) β€” go forth and negate responsibly πŸ§šβ€β™€οΈπŸŒΈ

πŸ“¦ where this page comes from