std::indire...y_predicate(3)

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

πŸ’– NAME πŸ’–

std::indirect_binary_predicate β€” literally the same thing again bestie, std::indirect_binary_predicate 🫢

Okay so real talk, this page is from the C++ Standard Libary manual (yes that's how it's spelled on the page, don't come for me πŸ’€) and it's all about one very specific little concept. Let's get into it ✨


✨ SYNOPSIS ✨

First things first, where does it live? Defined in header <iterator> πŸŽ€

template< class F, class I1, class I2 >

concept indirect_binary_predicate =
    std::indirectly_readable<I1> &&
    std::indirectly_readable<I2> &&
    std::copy_constructible<F> &&
    std::predicate<F&, std::iter_value_t<I1>&,
std::iter_value_t<I2>&> &&
    std::predicate<F&, std::iter_value_t<I1>&,
(since C++20)
std::iter_reference_t<I2>> &&
    std::predicate<F&, std::iter_reference_t<I1>,
std::iter_value_t<I2>&> &&
    std::predicate<F&, std::iter_reference_t<I1>,
std::iter_reference_t<I2>> &&

    std::predicate<F&, std::iter_common_reference_t<I1>,
std::iter_common_reference_t<I2>>;

It's been around since C++20, and yes, that whole thing is one giant && chain. It's giving "concept with a lot of trust issues" 😭 but honestly? Iconic.

So what is it actually doing? The concept indirect_binary_predicate specifies requirements for algorithms that call binary predicates as their arguments. That's the whole gig 🌸

And here's the key difference between this and std::predicate, bestie β€” write this down:

indirect_binary_predicate is applied to the types that I1 and I2 reference, not to I1 and I2 themselves. πŸ‘‘

That's it. That's the plot twist. The way it peeks through the iterator instead of looking at the iterator directly? Main character energy fr.


🌈 Semantic requirements 🌈

F, I1, and I2 model indirect_binary_predicate only if all the concepts it subsumes are modeled. No shortcuts, no vibes-only modeling, no cap πŸ’…


πŸ¦‹ the vibes, summarised πŸ¦‹

  • std::indirectly_readable<I1> β€” I1 has to be readable, non-negotiable
  • std::indirectly_readable<I2> β€” same energy for I2, equality slay
  • std::copy_constructible<F> β€” your predicate F must be copy constructible, it's literally the bare minimum
  • std::predicate<F&, std::iter_value_t<I1>&, std::iter_value_t<I2>&> β€” value refs, value refs πŸ“
  • std::predicate<F&, std::iter_value_t<I1>&, std::iter_reference_t<I2>> β€” value ref meets reference
  • std::predicate<F&, std::iter_reference_t<I1>, std::iter_value_t<I2>&> β€” the other way round, we stan symmetry
  • std::predicate<F&, std::iter_reference_t<I1>, std::iter_reference_t<I2>> β€” reference meets reference ✨
  • std::predicate<F&, std::iter_common_reference_t<I1>, std::iter_common_reference_t<I2>> β€” and the common reference finale, the closing number, the bows πŸŽ€

Every single one of those has to hold. All of them. It's an all-or-nothing concept, iykyk πŸ’œ


lowkey a warning bestie: if even one of those std::predicate checks fails, or I1/I2 aren't std::indirectly_readable, or F isn't std::copy_constructible, then the concept is simply not satisfied. There's no partial credit, no half-modeling, nada. πŸ™ˆ

🧚 source & sign-off 🧚

This little beauty came from http://cppreference.com, dated 2024.06.10, and the manual page is std::indire...y_predicate(3) β€” yes the title got truncated, she's mysterious like that πŸ’…

Go forth and model your concepts correctly, bestie. Slay, periodt, and may all your predicates be std::predicate ⭐πŸ”₯πŸ‘‘

πŸ“¦ where this page comes from