Modern C++
Modern C++ encompasses C++11 through C++20 and C++23. It emphasizes type safety, RAII, zero-cost abstractions, compile-time evaluation, and expressive standard library utilities.
- C++23:
std::print/println,std::expected(monadic error handling),std::string::contains,std::mdspan, multidimensional subscriptoperator[]. - C++20: Concepts, Ranges, Coroutines, Modules, Three-way comparison (
<=>),std::format,std::span. - C++17: Structured bindings,
std::string_view,std::optional,std::variant,std::filesystem,if constexpr. - C++14: Generic lambdas,
std::make_unique, return type deduction. - C++11: Smart pointers (
unique_ptr,shared_ptr), move semantics & rvalue references, lambdas,auto,nullptr.
Modern Ownership & RAII
Resource Acquisition Is Initialization (RAII) ties resource management directly to object lifetime:
-
Resource acquisition occurs in the constructor.
-
Resource release occurs in the destructor.
-
Read more: Smart Pointers
Concepts & Constraints (C++20)
Concepts specify compile-time template requirements, eliminating cryptic template error traces:
#include <concepts>
template <typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;
template <Numeric T>
T add(T a, T b) {
return a + b;
}
// Or using terse syntax:
auto multiply(Numeric auto a, Numeric auto b) {
return a * b;
}
Ranges & Views (C++20 / C++23)
Ranges allow composable, lazy pipeline transformations over collections without manual iterator pairs:
#include <iostream>
#include <vector>
#include <ranges>
std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8};
auto even_squares = numbers
| std::views::filter([](int n) { return n % 2 == 0; })
| std::views::transform([](int n) { return n * n; });
for (int val : even_squares) {
std::cout << val << " "; // 4 16 36 64
}
Modern Printing & Formatting (std::format / std::print)
std::format (C++20) and std::print (C++23) provide safe, extensible, high-performance replacements for printf and std::cout:
#include <format>
#include <print>
// C++20 formatting
std::string msg = std::format("User ID: {}, Balance: ${:.2f}", 101, 45.5);
// C++23 direct printing (faster than cout, eliminates printf formatting vulnerabilities)
std::println("Hello, {}! You have {} unread messages.", "Sam", 5);
Monadic Error Handling (std::expected, C++23)
Represents either an expected value of type T or an unexpected error of type E, offering an efficient alternative to exceptions:
#include <expected>
#include <string>
enum class ParseError { kInvalidChar, kOverflow };
std::expected<int, ParseError> parse_number(std::string_view str) {
if (str.empty()) return std::unexpected(ParseError::kInvalidChar);
// ...
return 42;
}
std::span (C++20)
A non-owning view over any contiguous sequence of objects (C arrays, std::vector, std::array):
#include <span>
#include <vector>
void process_data(std::span<const int> data) {
for (int item : data) {
// ...
}
}
std::vector<int> vec = {1, 2, 3};
int raw_arr[] = {4, 5, 6};
process_data(vec); // Works seamlessly without copying
process_data(raw_arr); // Works seamlessly
Modules (C++20)
Modules provide component boundaries that compile once, eliminating header file inclusion overhead and macro leakage:
// math.ixx / math.cppm
export module math;
export int square(int x) {
return x * x;
}
// main.cpp
import math;
import <iostream>;
int main() {
std::cout << square(5) << '\n';
}
Coroutines (C++20)
Functions that can suspend and resume execution via co_await, co_yield, or co_return. Commonly used for asynchronous I/O and lazy generator sequences.
Designated Initializers (C++20)
struct Config {
std::string host = "localhost";
int port = 8080;
bool use_ssl = false;
};
Config cfg = {
.port = 9000,
.use_ssl = true,
};
Spaceship Operator (<=>, C++20)
Auto-generates all 6 relational comparison operators (==, !=, <, <=, >, >=):
#include <compare>
struct Version {
int major;
int minor;
int patch;
auto operator<=>(const Version&) const = default;
};

