std::revers...::operator[](3)
π std::reverse_iterator::operator[] π
okay so bestie, welcome to the C++ Standard Libary manual (yes that's the manual name, don't come for me), and today's main character is std::reverse_iterator::operator[] β same name twice in the NAME section, iconic of it honestly. It's giving "I contain multitudes" but make it a subscript operator. π¦
β¨ NAME β¨
std::reverse_iterator::operator[] β literally std::reverse_iterator::operator[]. That's the name. That's the whole name. Periodt. π
π Synopsis π
until C++17 β no constexpr, we were all just vibing:
/* unspecified */ operator[]( difference_type n ) const;
since C++17 β glow-up era, constexpr entered the chat:
constexpr /* unspecified */ operator[]( difference_type n ) const;
π Parameters π
nβ position relative to the current location. that's it, that's the whole parameter, she's low maintenance π«Ά
π Return value π
A reference to the element at that relative location, which is to say:
base()[-n - 1]
yes the minus sign is on the n. yes it's reversed. she's a reverse iterator, what did you expect ππ₯
π§ Notes π§
okay this is the messy lore part, buckle up. The return type was changed by LWG386 to be unspecified because the return type of the underlying iterator's operator[] was also unspecified at the time. Like, nobody knew what it was. Mystery. Unknowable. π
BUT β as of N3066, the return type of a LegacyRandomAccessIterator's operator[] is required to be convertible to reference. In all common implementations, the return type of reverse_iterator::operator[] is declared to be reference. so like, in practice we all know what it is. β¨
See also LWG2595. iykyk. π
πΈ Example πΈ
// Run this code
#include <array>
#include <cstddef>
#include <iostream>
#include <iterator>
#include <list>
#include <vector>
int main()
{
int a[]{0, 1, 2, 3};
std::reverse_iterator<int*> iter1{std::rbegin(a)};
for (std::size_t i{}; i != std::size(a); ++i)
std::cout << iter1[i] << ' '; // decltype(iter1[i]) is `int&`
std::cout << '\n';
std::vector v{0, 1, 2, 3};
std::reverse_iterator<std::vector<int>::iterator> iter2{std::rbegin(v)};
for (std::size_t i{}; i != std::size(v); ++i)
std::cout << iter2[i] << ' '; // decltype(iter2[i]) is `int&`
std::cout << '\n';
// constexpr context
constexpr static std::array<int, 4> z{0, 1, 2, 3};
constexpr std::reverse_iterator<decltype(z)::const_iterator> iter3{std::crbegin(z)};
static_assert(iter3[1] == 2);
std::list li{0, 1, 2, 3};
std::reverse_iterator<std::list<int>::iterator> iter4{std::rbegin(li)};
*iter4 = 42; // OK
// iter4[0] = 13; // compilation error: the underlying iterator
// does not model the random access iterator
}
and yes bestie, that last commented-out line is a compilation error on purpose β the underlying iterator doesn't model the random access iterator. std::list is a linked-list girlie, she does not do random access, do not try her. π
π Output π
3 2 1 0
3 2 1 0
look at her go. reversed. flawless. ate and left no crumbs. π₯
π¦ Defect reports π¦
The following behavior-changing defect reports were applied retroactively to previously published C++ standards. time travel but make it standardization π«
LWG 386β applied toC++98β behavior as published: the return type wasreferenceβ correct behavior: made unspecified.
β See also β
operator*β accesses the pointed-to elementoperator->(public member function)
okay that's the whole page, you're welcome, go write something reversed and slay πβ¨
sign-off besties: this lil artifact came from http://cppreference.com, dated 2024.06.10, and the page was std::revers...::operator[](3) β mwah, ily, bye ππ«Ά
π¦ where this page comes from
- nixpkgs unstable: stdman 2024.07.05
- opensuse-leap 16.0: stdman 2024.07.05-bp160.1.9 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms