std::ranges::cbegin(3)

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

okay so this is the std::ranges::cbegin(3) page from the C++ Standard Libary, and we are gonna make it make sense, bestie πŸ’–βœ¨

✨ NAME ✨

  • std::ranges::cbegin β€” std::ranges::cbegin (yes, that is the whole name section, she said what she said πŸ’…)

🌸 Synopsis 🌸

Defined in header <ranges>

Defined in header <iterator>

inline namespace /* unspecified */ {

    inline constexpr /* unspecified */ cbegin = /*      (since C++20)
unspecified */;
(customization point object)

}

Call signature

template< class T >

    requires /* see below */                            (since C++20)

constexpr /* see below */ auto cbegin( T&& t );

Until C++23, this returns an iterator to the first element of the const-qualified argument. Since C++23, it returns a constant iterator to the first element of the argument. πŸ¦‹

There is also a diagram named range-begin-end.svg on the page β€” not me inventing lore, that is literally the file name πŸŽ€

Let CT be (this whole definition is until C++23, bestie):

  • const std::remove_reference_t<T>& if the argument is an lvalue (i.e. T is an lvalue reference type),
  • const T otherwise.

A call to ranges::cbegin is expression-equivalent to ranges::begin(static_cast<CT&&>(t)).

If the argument is an lvalue or ranges::enable_borrowed_range<std::remove_cv_t<T>> is true, then a call to ranges::cbegin is expression-equivalent to:

  • std::const_iterator<decltype(U)>(U) for some expression U equivalent to ranges::begin(/*possibly-const-range*/(t)). (since C++23)

In all other cases, a call to ranges::cbegin is ill-formed, which can result in substitution failure when the call appears in the immediate context of a template instantiation. 😭

The return type models std::input_or_output_iterator and constant-iterator (since C++23) in all cases.

πŸ’œ Notes πŸ’œ

For an lvalue range e of type T, ranges::cbegin(e) is equivalent to:

ranges::begin(std::as_const(e)).

(until C++23)

And since C++23, it is equivalent to:

  • ranges::begin(e) if T models constant_range.
  • Otherwise, ranges::begin(std::as_const(e)) if const T models constant_range.
  • Otherwise, std::basic_const_iterator(ranges::begin(e)).

🧚 Example 🧚

The page says // Run this code, so here is the whole thing, no cap:

// Run this code

#include <cassert>
#include <ranges>
#include <vector>

int main()
{
    std::vector v{3, 1, 4};
    auto vi = std::ranges::cbegin(v);
    assert(3 == *vi);
    ++vi; // OK, constant-iterator object is mutable
    assert(1 == *vi);
    // *vi = 13; // Error: constant-iterator points to an immutable element

    int a[]{3, 1, 4};
    auto ai = std::ranges::cbegin(a); // cbegin works with C-arrays as well
    assert(3 == *ai and *(ai + 1) == 1);
    // *ai = 13; // Error: read-only variable is not assignable
}

πŸŽ€ See also πŸŽ€

  • ranges::begin β€” returns an iterator to the beginning of a range (C++20) (customization point object)
  • begin β€” (listed all by itself on the page; no extra description attached, bestie πŸ’…)
  • cbegin β€” returns an iterator to the beginning of a container or array (C++11) (function template) (C++14)

okay bye bestie, this was the std::ranges::cbegin(3) page from http://cppreference.com, dated 2024.06.10 β€” mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from