std::indire...ry_invocable(3)

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

πŸ’… std::indirectly_unary_invocable, std::indirectly_regular_unary_invocable

okay so bestie, we're in the C++ Standard Library corner of the manual β€” this page lives under std::indire...ry_invocable(3) and honestly the title got truncated by the typesetter, not us πŸ’€. Two concepts, one page, let's get into it πŸŽ€


✨ NAME ✨

std::indirectly_unary_invocable, std::indirectly_regular_unary_invocable β€” yeah that's the whole name, it's long, it's iconic, it's giving "my mom named me after the entire concept list" πŸ‘‘

✨ Synopsis ✨

Both of these cuties are defined in header <iterator> β€” no cap, that's the whole include 🌸

          Defined in header <iterator>
          template< class F, class I >

              concept indirectly_unary_invocable =
                  std::indirectly_readable<I> &&
                  std::copy_constructible<F> &&
                  std::invocable<F&, std::iter_value_t<I>&> &&
       (since C++20)
                  std::invocable<F&, std::iter_reference_t<I>> &&
                  std::invocable<F&, std::iter_common_reference_t<I>> &&
                  std::common_reference_with<
                      std::invoke_result_t<F&, std::iter_value_t<I>&>,

                      std::invoke_result_t<F&, std::iter_reference_t<I>>>;
          template< class F, class I >

              concept indirectly_regular_unary_invocable =
                  std::indirectly_readable<I> &&
                  std::copy_constructible<F> &&
                  std::regular_invocable<F&, std::iter_value_t<I>&> &&
                  std::regular_invocable<F&, std::iter_reference_t<I>> &&
       (since C++20)
                  std::regular_invocable<F&, std::iter_common_reference_t<I>>
          &&
                  std::common_reference_with<
                      std::invoke_result_t<F&, std::iter_value_t<I>&>,

                      std::invoke_result_t<F&, std::iter_reference_t<I>>>;

so like, read that as a vibe check list: std::indirectly_readable<I> βœ…, std::copy_constructible<F> βœ…, and then a whole stack of std::invocable / std::regular_invocable checks βœ…βœ…βœ…, plus a std::common_reference_with<...> on the two std::invoke_result_t types. The (since C++20) tag is doing a lot of work in there, don't @ me 😭

✨ DESCRIPTION ✨

Okay so the concepts indirectly_unary_invocable and indirectly_regular_unary_invocable specify requirements for algorithms that call (regular) unary invocables as their arguments πŸ”₯

The whole key difference between these concepts and std::invocable is that they're applied to the type that I references, rather than to I itself. That's it, that's the plot twist πŸ’… it's looking through the iterator, not at it. iykyk πŸ¦‹

🌈 Semantic requirements

Each concept is modeled by F and I only if all the concepts it subsumes are modeled. That's the whole rule β€” no shortcuts, no vibes-based modeling, bestie, it's all or nothing ✨

✨ NOTES ✨

The distinction between indirectly_unary_invocable and indirectly_regular_unary_invocable is purely semantic 🌸 So the compiler isn't gonna hold your hand and diff them for you β€” that part's on you, and yes that's lowkey the scary part πŸ™ˆ

like, they look similar and they're not the same thing in meaning, so don't come for me when the compiler says "no" β€” it's a semantics situation, not a syntax situation πŸ’€

and that's the page, babes 🫢 signed off from http://cppreference.com, version 2024.06.10 β€” go forth and constrain your templates responsibly, ily πŸŽ€πŸ’–

πŸ“¦ where this page comes from