std::forwar..._list::cend(3)

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

πŸ’… std::forward_list::end, std::forward_list::cend

okay bestie, welcome to the C++ Standard Library (that's the manual name btw, we're in <forward_list> territory) and today we're talking about the end of things β€” literally. This page covers std::forward_list::end and std::forward_list::cend, and no, that's not a typo, they're two separate besties living on the same page 🫢

✨ Synopsis ✨

iterator end() noexcept;              (1) (since C++11)
const_iterator end() const noexcept;  (2) (since C++11)
const_iterator cend() const noexcept; (3) (since C++11)

So what do these do? They hand you an iterator pointing to the element following the last element of the forward_list. Yes, the element that doesn't exist. The phantom element. The one past the end πŸ‘»

⚠️ Heads up bestie: this element acts as a placeholder only. Trying to access it is undefined behavior. Not "oops it crashes," not "you get garbage," just undefined β€” the compiler is allowed to do literally whatever. Don't touch it. Periodt. πŸ’€

There's also a little diagram floating around for this, range-begin-end.svg β€” it's giving visual aid, very helpful, go look at it 🌸

πŸŽ€ Parameters πŸŽ€

None! Zero. Nothing. (none). She takes no arguments, she's low maintenance ✨

πŸ’– Return value πŸ’–

An iterator to the element following the last element. That's it, that's the whole vibe.

πŸ¦‹ Complexity πŸ¦‹

Constant. O(1). She's fast, she's iconic, she does not loop, she does not care about your container's size πŸ‘‘

🌈 Example 🌈

This is the good part, run this code:

// Run this code

#include <algorithm>
#include <iostream>
#include <numeric>
#include <string>
#include <forward_list>

int main()
{
    std::forward_list<int> nums{1, 2, 4, 8, 16};
    std::forward_list<std::string> fruits{"orange", "apple", "raspberry"};
    std::forward_list<char> empty;

    // Print forward_list.
    std::for_each(nums.begin(), nums.end(), [](const int n) { std::cout << n << ' '; });
    std::cout << '\n';

    // Sums all integers in the forward_list nums (if any), printing only the result.
    std::cout << "Sum of nums: "
              << std::accumulate(nums.begin(), nums.end(), 0) << '\n';

    // Prints the first fruit in the forward_list fruits, checking if there is any.
    if (!fruits.empty())
        std::cout << "First fruit: " << *fruits.begin() << '\n';

    if (empty.begin() == empty.end())
        std::cout << "forward_list 'empty' is indeed empty.\n";
}

Notice how that last check uses empty.begin() == empty.end() β€” that's the classic "is this thing actually empty" move, and it works because of the end() we're documenting. Main character energy fr fr πŸ’…

⭐ Output ⭐

1 2 4 8 16
Sum of nums: 31
First fruit: orange
forward_list 'empty' is indeed empty.

She ate and left no crumbs πŸ”₯

πŸ‘‘ See also πŸ‘‘

  • begin β€” returns an iterator to the beginning
  • cbegin β€” same idea, const flavored (public member function)
  • end
  • cend β€” returns an iterator to the end of a container or array β€” (C++11) (function template) β€” (C++14)

k that's the whole page, bestie 🧚 go forth and never dereference an end iterator. mwah πŸ’œ

<sourcetag>source/version cppreference.com, dated 2024.06.10 β€” that's the footer tea, see u on the next page 🌸</sourcetag>

πŸ“¦ where this page comes from