█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/C++/Modern C++ (C++17/20)
50 minAdvanced

Modern C++ (C++17/20)

After this lesson, you will be able to: Use modern C++17/20 features: structured bindings, std::optional, std::variant, std::span, ranges, concepts.

C++17 and C++20 added features that make C++ feel less like 1990s C++ and more like a modern language. Use them.

Prerequisites:Move semantics

Structured bindings (C++17)

Destructure tuples, pairs, structs, arrays.

tsx
#include <map>
#include <tuple>
std::map<std::string, int> ages = {{"Alex", 30}, {"Sam", 25}};
for (const auto& [name, age] : ages) {
std::cout << name << " is " << age << "\n";
}
// Return multiple values
std::tuple<int, std::string> getData() { return {42, "hello"}; }
auto [num, text] = getData();
// Decompose a struct
struct Point { int x; int y; };
Point p = {3, 4};
auto [x, y] = p;

std::optional (C++17)

A value that might not be there, no nullable pointers needed.

tsx
#include <optional>
std::optional<User> findUser(int id) {
if (id == 1) return User("Alex", 30);
return std::nullopt;
}
auto u = findUser(2);
if (u) {
std::cout << u->name() << "\n";
}
// u.value_or(defaultUser) for fallback

std::variant (C++17) — type-safe union

Sum types in C++.

tsx
#include <variant>
std::variant<int, std::string, double> v = 42;
v = std::string("hello");
// std::visit applies the right overload
std::visit([](const auto& val) {
std::cout << "value: " << val << "\n";
}, v);

std::span (C++20) — non-owning view of contiguous data

Replaces `T*` + size pairs.

tsx
#include <span>
#include <vector>
void process(std::span<int> data) {
for (int x : data) std::cout << x << " ";
}
std::vector<int> v = {1, 2, 3};
int arr[] = {4, 5, 6};
process(v); // works with vector
process(arr); // works with C array
process({v.data() + 1, 2}); // works with pointer + size

Ranges + views (C++20)

Composable lazy pipelines.

tsx
#include <ranges>
#include <vector>
std::vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto pipeline = nums
| std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * x; })
| std::views::take(3);
for (int x : pipeline) std::cout << x << " ";
// outputs: 4 16 36

Common mistakes

Storing references in std::optional (use std::optional<std::reference_wrapper<T>>). Skipping the `auto& [a, b] = ...` form when you want to modify (you'll get copies). Not checking optional before dereferencing (`*opt` on empty = UB). Sticking to C++11/14 syntax when C++20 is available, older code reads as 'didn't keep up.'

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Move Semantics
Back to C++
Concurrency in C++→