Modern C++11, C++14, C++17, and C++20
Explore major modern C++ features and learn how to select a language standard.
Learning objectives
- Recognize major modern C++ language milestones.
- Use range-based for, auto, and nullptr.
- Understand structured bindings and optional.
- Recognize C++20 concepts, ranges, and span.
Prerequisites: functions, classes, vectors, and basic templates. Review Functions, std::vector, Templates, and Smart pointers first.
Why modern C++?
C++ has evolved through multiple standards. Modern features make code safer, clearer, and more expressive. A compiler's support depends on its version and standard library, so select the language mode deliberately and check support for each feature.
C++11 and C++14
autotype deduction reduces repetitive type names.- Range-based
forloops make sequence traversal clearer. nullptris the dedicated null pointer literal.- Smart pointers support RAII ownership.
- Move semantics can transfer resources efficiently.
- Generic lambdas in C++14 allow
autoparameters.
C++17: structured bindings and optional
#include <optional>
#include <string>
#include <utility>
std::pair<int, std::string> student{7, "Asha"};
auto [roll, name] = student;
std::optional<int> find_score(bool found) {
if (found) return 95;
return std::nullopt;
}Structured bindings give names to elements of a pair-like or aggregate object. std::optional<T> represents a value that may or may not be present.
C++20: concepts, ranges, and span
Concepts let templates state requirements on types. Ranges provide composable views and algorithms over ranges. std::span provides a non-owning view over a contiguous sequence; it does not own the elements and must not outlive them.
#include <span>
#include <concepts>
template <std::integral T>
T twice(T value) {
return value * 2;
}
void print_values(std::span<const int> values);This is an introductory illustration. Concepts, ranges, and views have detailed rules that deserve focused lessons and careful compiler support checks.
Choose the right standard
Use the newest standard your project and toolchain support, but do not assume every environment has the same compiler version. For learning and portability in this course, C++17 is the baseline. C++20 examples are labelled explicitly.
Common mistakes
- Using a newer feature without selecting a compatible standard.
- Assuming the compiler and standard library support exactly the same feature set.
- Thinking span owns its elements.
- Assuming optional always contains a value; check it before access.
Practice
- Rewrite an indexed vector loop as a range-based for loop.
- Use optional to represent a search result that may be absent.
- Compile a structured-binding example in C++17 mode.
- Explain why a span must not outlive the array or vector it views.
Practice solutions
Show worked solutions
- Use a range-based loop:
for (const auto& value : values) { std::cout << value << '\n'; }. It visits each element without manually managing an index. - Return
std::optional<std::size_t>from a search function. Return the matching index when found andstd::nulloptotherwise; callers check the optional before reading the index. - In C++17, include
<utility>and writestd::pair<int, std::string> item{7, "Asha"}; auto [id, name] = item;. Compile with a C++17 language mode. - A span is only a view. The array or vector it refers to must outlive every use of the span; returning a span to a local array or local vector would leave a dangling view.
Check your understanding
Does std::span own the memory it views?
Answer: No. It is a non-owning view, so the underlying sequence must remain alive and valid while the span is used.
Summary
Modern C++ adds safer ownership tools, concise syntax, generic programming support, and range abstractions. Learn which standard introduced a feature and verify compiler/library support before using it.