std::unreac...ble_sentinel(3)
π NAME π
okay so bestie, this is the std::unreachable_sentinel_t / std::unreachable_sentinel page from the C++ Standard Libary manual β yes, the header is out here truncating the title like std::unreac...ble_sentinel(3), and the NAME line is literally std::unreachable_sentinel_t,std::unreachable_sentinel. Weβre folding that manual-name moment in right here instead of copy-pasting the header line, periodt. π
β¨ Synopsis β¨
Defined in header <iterator>
struct unreachable_sentinel_t; (1)
(since C++20)
inline constexpr unreachable_sentinel_t unreachable_sentinel{}; (2)
(since C++20)
unreachable_sentinel_tis an empty class type that can be used to denote the βupper boundβ of an unbounded interval. π¦unreachable_sentinelis a constant of typeunreachable_sentinel_t.
π Non-member functions π
operator==β compares anunreachable_sentinel_twith a value of any(C++20)weakly_incrementabletype;(function template). π₯
π¦ operator==(std::unreachable_sentinel_t) π¦
Hereβs the signature vibe:
template<std::weakly_incrementable I>
friend constexpr bool operator==( unreachable_sentinel_t, const I& )
noexcept
{ return false; }
Itβs (since C++20), and itβs literally noexcept too. π
unreachable_sentinel_t can be compared with any weakly_incrementable type and the result is always false β yes, always, no cap. Itβs giving βI am the sentinel that is never reachedβ energy. π
Also important: this function template is not visible to ordinary unqualified or qualified lookup, and can only be found by argument-dependent lookup when std::unreachable_sentinel_t is an associated class of the arguments. Thatβs the iykyk ADL lore. π§
π₯ Example π₯
This is the whole βRun this codeβ moment, verbatim bestie:
// Run this code
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <iterator>
template<class CharT>
constexpr std::size_t strlen(const CharT *s)
{
return std::ranges::find(s, std::unreachable_sentinel, CharT{}) - s;
}
template<class CharT>
constexpr std::size_t pos(const CharT *haystack, const CharT *needle)
{
// search(begin, unreachable_sentinel) is usually more efficient than
// search(begin, end) due to one less comparison per cycle.
// But "needle" MUST BE in the "haystack", otherwise the call is UB,
// which is a compile-time error in constexpr context.
return std::ranges::search(
haystack, std::unreachable_sentinel,
needle, needle + strlen(needle)
).begin() - haystack;
}
int main()
{
static_assert(strlen("The quick brown fox jumps over the lazy dog.") == 44);
static_assert(pos("const short int", "short") == 6);
// static_assert(pos("long int", "float")); // compile-time error
}
the commented-out // static_assert(pos("long int", "float")); // compile-time error is there to remind you that the "needle" MUST BE in the "haystack" β otherwise the call is UB, and in a constexpr context that UB shows up as a compile-time error. Not me being dramatic, thatβs literally the comment. π
π See also π
The See also lineup is ranges::iota_view and views::iota: ranges::iota_view is (C++20) (class template), views::iota is (C++20) (customization point object), and the description that shows up is βa view consisting of a sequence generated by repeatedly incrementing an initial value.β πΈ
source/version + date: http://cppreference.com, 2024.06.10 β mwah, thatβs the footer sign-off, bestie π
π¦ 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