std::common...perator*,->(3)

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

✨ NAME ✨

std::common...perator*,-> - std::common...perator*,-> β€” yes bestie, the NAME says it twice, and honestly? iconic. This is the std::common_iterator deref/arrow page from the C++ Standard Libary manual.


🌸 SYNOPSIS 🌸

okay so here’s the signature situation, no cap:

   constexpr decltype(auto) operator*();                         (1)
(since C++20)
   constexpr decltype(auto) operator*() const                    (2)
(since C++20)
       requires /*dereferenceable*/<const I>;
   constexpr auto operator->() const                             (3)
(since C++20)
       requires /* see description */;

πŸŽ€ Helper types πŸŽ€

and here’s the helper-type tea:

class /*proxy*/ {

    std::iter_value_t<I> keep_;
    constexpr proxy(std::iter_reference_t<I>&& x)
        : keep_(std::move(x)) {}
public:                                                       (4)
(exposition only*)
    constexpr const std::iter_value_t<I>* operator->() const
noexcept {
        return std::addressof(keep_);
    }

};

Short version: this thing returns a pointer or reference to the current element, or a proxy holding it. periodt.

🚨 undefined behavior warning, bestie: the behavior is undefined if the underlying std::variant member object var does not hold an object of type I, i.e. std::holds_alternative<I>(var) is equal to false. like… do not test fate with that one.

Let it denote the iterator of type I held by var, that is std::get<I>(var).

  • 1,2) Returns the result of dereferencing it.
  • 3) Returns a pointer or underlying iterator to the current element, or a proxy holding it:
    • Equivalent to return it;, if I is a pointer type or if the expression it.operator->() is well-formed.
    • Otherwise, equivalent to auto&& tmp = *it; return std::addressof(tmp);, if std::iter_reference_t<I> is a reference type.
    • Otherwise, equivalent to return proxy(*it);, where proxy is an exposition only class (4).

The expression in the requires-clause is equivalent to:

std::indirectly_readable<const I> && (
    requires(const I& i) { i.operator->(); } ||
    std::is_reference_v<std::iter_reference_t<I>> ||
    std::constructible_from<std::iter_value_t<I>, std::iter_reference_t<I>>
)

πŸ’œ PARAMETERS πŸ’œ

(none) β€” literally no parameters, she takes nothing.


🫢 RETURN VALUE 🫢

  • 1,2) Reference to the current element, or prvalue temporary. Equivalent to *it.
  • 3) Pointer or iterator to the current element or proxy holding it as described above.

πŸ“ EXAMPLE πŸ“

There’s a // Run this code vibe here, so go off:

#include <complex>
#include <initializer_list>
#include <iostream>
#include <iterator>

using std::complex_literals::operator""i;

int main()
{
    const auto il = {1i, 3.14 + 2i, 3i, 4i, 5i};

    using CI = std::common_iterator<
        std::counted_iterator<decltype(il)::iterator>,
        std::default_sentinel_t>;

    CI ci{std::counted_iterator{std::next(begin(il), 1), std::ssize(il)
       - 1}};

    std::cout << *ci << ' ' << ci->real() << '\n';
}

🌈 Output 🌈

(3.14,2) 3.14

πŸ‘‘ DEFECT REPORTS πŸ‘‘

okay so these behavior-changing defect reports got applied retroactively to previously published C++ standards β€” not me doing archaeology, but go off:

  • LWG 3574 β€” applied to C++20. As published: variant was fully constexpr (P2231R1) but common_iterator was not. Correct behavior: also made constexpr.
  • LWG 3595 β€” applied to C++20. As published: functions of the proxy type lacked constexpr and noexcept. Correct behavior: added.
  • LWG 3672 β€” applied to C++20. As published: operator-> might return by reference in usual cases. Correct behavior: always returns by value.

πŸ¦‹ SEE ALSO πŸ¦‹

  • constructor β€” constructs a new iterator adaptor (C++20) (public member function).

source/version: http://cppreference.com Β· date: 2024.06.10 Β· page: std::common...perator*,->(3) β€” bye bestie, go deref something cute πŸ’–βœ¨

πŸ“¦ where this page comes from