Modern C++ adds type tools that reduce boilerplate without giving up safety, if you know where they hide footguns. This lesson ties together auto, views, exact-width integers, and explicit conversions used throughout the rest of the course and in capstone 10.4.
auto: convenience with rules
Use auto when the initializer makes the type obvious (auto it = vec.begin();) or when spelling a long type adds noise. auto drops top-level const and references unless you write const auto&, auto&, or auto&& deliberately.
Structured bindings
Structured bindings unpack tuple-like types into named variables. Bindings can be by value, reference, or const reference, lifetime rules follow what you bind to.
std::optional and std::variant (recap)
Lesson 4.5 introduced std::variant for type-safe runtime dispatch without virtual tables. Pair it with std::optional<T> when a computation may legitimately produce no value, prefer that over sentinel integers or null pointers.
Exact-width integers for binary work
For wire formats, checksums, and hardware registers, use <cstdint> types (std::uint32_t, std::int64_t, etc.) when you need a documented width. For everyday loop indices, prefer the container's size() type or std::size_t and compare signed/unsigned deliberately, Lesson 1.3 showed overflow pitfalls.
std::span: bounded non-owning ranges
std::span<T> is a pointer plus length to contiguous caller-owned storage. It replaces the error-prone (T* data, size_t n) pattern and accepts std::array, C arrays, and std::vector without copying.
std::string_view lifetime (critical)
std::string_view is a non-owning view of characters. It is fast for parameters, but every view must point at storage that outlives the view. Returning a string_view to a local std::string is the same dangling bug as Lesson 3.4, rewrite with an owning std::string or caller-provided buffer.
Explicit conversions
Use static_cast for checked, intentional conversions you can explain (numeric widening/narrowing after validation). Avoid reinterpret_cast for casual type punning, Lesson 3.6 shows std::bit_cast for same-size representations. Do not chain implicit conversions through several types; make each conversion visible at the call site.
[[nodiscard]] on functions returning std::optional, error types, or handles reminds callers not to drop return values. It does not change runtime behavior, but it catches ignored failures in -Wall builds.
Practice: write std::optional<std::string_view> findToken(std::string_view haystack, std::string_view needle) that returns a substring view into haystack. Explain why the view remains valid after the function returns.