C++
Programming Language Guide
A comprehensive reference: classes, templates, STL, smart pointers, move semantics, lambdas,
concurrency, and modern C++ best practices.
Paradigm Multi-paradigm: OOP, generic, procedural, functional
Typing Static, strong, with template metaprogramming
Created by Bjarne Stroustrup, Bell Labs — first released 1985
Standards C++98 · C++11 · C++14 · C++17 · C++20 · C++23
Compilers GCC (g++), Clang (clang++), MSVC, Intel icpx
License ISO standard; compilers vary (open/proprietary)
Use cases Games, OS, compilers, finance, embedded, HPC, GUI
Table of Contents
1. Introduction & C++ Evolution
2. Compilation & Build Systems
3. Classes & Object-Oriented Programming
4. Operator Overloading
5. Templates & Generic Programming
6. Smart Pointers & RAII
7. The Standard Template Library (STL)
8. Lambdas & std::function
9. Move Semantics & Rvalue References
10. Error Handling & Exceptions
11. Concurrency (std::thread, futures)
12. C++20 Features: Concepts, Ranges, Coroutines
13. Build Systems & Package Management
14. Standard Library Quick Reference
15. Modern C++ Best Practices
C++ Guide Page 1 of 8
1. Introduction & C++ Evolution
C++ began as "C with Classes" in 1979 and has evolved into a multi-paradigm language supporting
procedural, object-oriented, generic, and functional styles. C++11 was a watershed release —
introducing move semantics, lambdas, smart pointers, and a rich concurrency library. Each subsequent
standard (14, 17, 20, 23) has added vocabulary types, algorithms, and language features that make
C++ safer and more expressive while retaining zero-overhead abstractions and C compatibility.
Standard Key additions
C++98/03 Templates, STL, exceptions, namespaces, bool
C++11 auto, move semantics, lambdas, unique_ptr/shared_ptr, nullptr, range-for, initialiser lists, std::thread
C++14 Generic lambdas, relaxed constexpr, make_unique, binary literals
C++17 std::optional, std::variant, std::any, structured bindings, if constexpr, parallel algorithms, std::filesystem
C++20 Concepts, Ranges, Coroutines, std::format, three-way <=> operator, modules (experimental), std::span
C++23 std::expected, std::print, std::mdspan, improved ranges & views
2. Compilation & Build Systems
# Compile single file g++ -std=c++20 -Wall -Wextra -pedantic [Link] -o app #
[Link] (minimal) cmake_minimum_required(VERSION 3.20) project(MyApp)
set(CMAKE_CXX_STANDARD 20) add_executable(app [Link] [Link])
target_compile_options(app PRIVATE -Wall -Wextra) # Build with CMake cmake -B build
-DCMAKE_BUILD_TYPE=Release cmake --build build # Conan 2 (package manager) conan install
. --output-folder=build --build=missing # or vcpkg: vcpkg install fmt spdlog
nlohmann-json
C++ Guide Page 2 of 8
3. Classes & Object-Oriented Programming
#include #include class Vehicle { public: Vehicle(std::string make, int year) :
make_(std::move(make)), year_(year) {} virtual ~Vehicle() = default; // virtual
destructor virtual std::string describe() const; // pure virtual possible const
std::string& make() const { return make_; } int year() const { return year_; } private:
std::string make_; int year_; }; class ElectricCar : public Vehicle { public: using
Vehicle::Vehicle; std::string describe() const override { return make() + " (" +
std::to_string(year()) + ") — electric"; } }; // Rule of Five (if you need one, define
all five) class Buffer { public: explicit Buffer(size_t n) : data_(new int[n]), size_(n)
{} ~Buffer() { delete[] data_; } Buffer(const Buffer& o) : Buffer(o.size_) {
std::copy(o.data_, o.data_+size_, data_); } Buffer& operator=(const Buffer&); //
implement similarly Buffer(Buffer&& o) noexcept : data_(o.data_), size_(o.size_) {
o.data_=nullptr; o.size_=0; } Buffer& operator=(Buffer&&) noexcept;// implement
similarly private: int* data_; size_t size_; };
4. Operator Overloading
struct Vec2 { double x, y; Vec2 operator+(const Vec2& o) const { return {x+o.x, y+o.y}; }
Vec2& operator+=(const Vec2& o) { x+=o.x; y+=o.y; return *this; } bool operator==(const
Vec2&) const = default; // C++20 // Stream insertion friend std::ostream&
operator<<(std::ostream& os, const Vec2& v) { return os << "(" << v.x << ", " << v.y <<
")"; } // Spaceship / three-way comparison (C++20) auto operator<=>(const Vec2&) const =
default; };
5. Templates & Generic Programming
// Function template template T max_val(T a, T b) { return (a > b) ? a : b; } // Class
template template class FixedArray { public: T& operator[](size_t i) { return data_[i]; }
size_t size() const { return N; } private: T data_[N]; }; FixedArray arr; arr[0] = 42; //
Variadic template template void log(Args&&... args) { (std::cout << ... << args) << '\n';
} // Concept (C++20) template concept Addable = requires(T a, T b) { a + b; }; template T
add(T a, T b) { return a + b; }
C++ Guide Page 3 of 8
6. Smart Pointers & RAII
#include // unique_ptr — sole ownership, zero overhead auto dog =
std::make_unique("Rex"); dog->bark(); // auto-deleted at end of scope // shared_ptr —
shared ownership via reference counting auto cat1 = std::make_shared("Luna"); { auto cat2
= cat1; // ref count = 2 cat2->purr(); } // ref count = 1 // cat1 still valid // weak_ptr
— breaks reference cycles std::weak_ptr wc = cat1; if (auto locked = [Link]()) {
locked->purr(); // safe access } // Custom deleter auto file =
std::unique_ptr(fopen("[Link]","r"), fclose); // RAII lock guard #include std::mutex mtx;
{ std::lock_guard lock(mtx); // critical section — mutex released automatically }
7. The Standard Template Library (STL)
Category Container / Type Use case
Sequence std::vector<T> Dynamic array, random access, cache-friendly
Sequence std::deque<T> Fast insert/remove at both ends
Sequence std::list<T> Frequent insert/remove in middle
Sequence std::array<T,N> Fixed-size array, stack allocated
Associative std::map<K,V> Sorted key-value, O(log n) lookup
Associative std::unordered_map<K,V>Hash key-value, O(1) avg lookup
Associative std::set<T> Unique sorted elements
Associative std::unordered_set<T> Unique elements, O(1) avg lookup
Adaptor std::stack / std::queueLIFO / FIFO adaptors over deque
Adaptor std::priority_queue<T> Heap-based max (or min) queue
Utility std::optional<T> Value-or-nothing (C++17)
Utility std::variant<T...> Type-safe union (C++17)
Utility std::span<T> Non-owning view of contiguous data (C++20)
8. Lambdas & std::function
#include #include #include std::vector v = {5, 2, 8, 1, 9, 3}; // Sort ascending
std::sort([Link](), [Link]()); // Lambda with capture int threshold = 4; auto big =
std::count_if([Link](), [Link](), [threshold](int n){ return n > threshold; }); //
Mutable lambda int calls = 0; auto counter = [calls]() mutable { return ++calls; }; //
std::function — type-erased callable std::function op; op = [](int a, int b){ return a+b;
}; op = std::multiplies(); // std::transform std::vector squares;
std::transform([Link](), [Link](), std::back_inserter(squares), [](int n){ return n*n;
});
C++ Guide Page 4 of 8
9. Move Semantics & Rvalue References
// lvalue vs rvalue int x = 5; // x is lvalue int&& r = 5; // rvalue reference //
std::move — cast to rvalue std::vector a = {1,2,3}; std::vector b = std::move(a); // a is
now valid-but-unspecified (empty) // Perfect forwarding with std::forward template void
wrapper(T&& arg) { process(std::forward(arg)); // preserves lvalue/rvalue-ness } // Move
constructor / assignment class String { char* data_; size_t len_; public: // Move
constructor String(String&& o) noexcept : data_(std::exchange(o.data_, nullptr)) ,
len_(std::exchange(o.len_, 0)) {} // Move assignment String& operator=(String&& o)
noexcept { if (this != &o;) { delete[] data_; data_ = std::exchange(o.data_,nullptr);
len_=o.len_; } return *this; } };
10. Error Handling & Exceptions
#include #include try { if (n < 0) throw std::invalid_argument("n must be >= 0"); auto
result = compute(n); } catch (const std::invalid_argument& e) { std::cerr << "Bad arg: "
<< [Link]() << '\n'; } catch (const std::exception& e) { std::cerr << "Error: " <<
[Link]() << '\n'; } catch (...) { std::cerr << "Unknown exception\n"; } // Custom
exception struct DatabaseError : public std::runtime_error { int code; DatabaseError(int
c, const std::string& msg) : std::runtime_error(msg), code(c) {} }; // noexcept — promise
not to throw (move ops, destructors) void safe_swap(int& a, int& b) noexcept { using
std::swap; swap(a, b); } // std::expected (C++23) — error without exceptions //
std::expected parse(std::string_view s);
11. Concurrency (std::thread, futures)
#include #include #include // Basic thread std::thread t([]{ std::cout << "hello from
thread\n"; }); [Link](); // Mutex + lock_guard std::mutex mtx; int counter = 0; auto inc
= [&]{ for (int i=0; i<1000; i++) { std::lock_guard lk(mtx); ++counter; } }; std::thread
t1(inc), t2(inc); [Link](); [Link](); // Async / future std::future fut =
std::async(std::launch::async, []{ return 42; }); int val = [Link](); // blocks until
ready // atomic — lock-free counter #include std::atomic ac{0}; ++ac; // thread-safe
C++ Guide Page 5 of 8
12. C++20 Features: Concepts, Ranges, Coroutines
// Concepts #include template T double_it(T x) { return x * 2; } // Ranges (replaces raw
begin/end everywhere) #include #include std::vector nums{1,2,3,4,5,6,7,8,9,10}; auto
even_squares = nums | std::views::filter([](int n){ return n%2==0; }) |
std::views::transform([](int n){ return n*n; }); for (int v : even_squares) std::cout <<
v << " "; // prints: 4 16 36 64 100 // std::format (C++20) #include std::string s =
std::format("Hello, {}! Pi={:.2f}", "world", 3.14); // Coroutine skeleton (C++20)
#include generator count_up(int from) { while (true) co_yield from++; } // Note:
generator type provided by library (e.g. cppcoro)
13. Build Systems & Package Management
Tool Type Notes
CMake Meta build system Industry standard; generates Makefile/Ninja/VS projects
Ninja Build system Fast parallel builds; used as CMake backend
Make Build system Classic Unix tool; Makefile-based
Bazel Build system Google's tool; great for monorepos
Meson Meta build system Fast, Python-based; growing popularity
Conan 2 Package manager Cross-platform C/C++ packages; cmake integration
vcpkg Package manager Microsoft-maintained; easy CMake integration
[Link] Package manager Lightweight CMake-native package manager
14. Standard Library Quick Reference
Header Provides
<iostream> std::cout, std::cin, std::cerr, std::endl
<string> std::string, std::to_string, std::stoi/stod
<vector> std::vector<T>
<algorithm> std::sort, std::find, std::transform, std::accumulate, 100+ algorithms
<memory> std::unique_ptr, std::shared_ptr, std::make_unique, std::make_shared
<functional> std::function, std::bind, std::ref, std::less, std::plus …
<filesystem> std::filesystem::path, directory_iterator, copy, exists (C++17)
<chrono> Duration, time_point, system_clock, steady_clock, sleep_for
<thread> std::thread, std::jthread (C++20)
<future> std::async, std::future, std::promise
<optional> std::optional<T>, std::nullopt (C++17)
<variant> std::variant<Ts...>, std::visit, std::get (C++17)
<format> std::format, std::vformat (C++20)
C++ Guide Page 6 of 8
Header Provides
<ranges> std::views, std::ranges algorithms (C++20)
C++ Guide Page 7 of 8
15. Modern C++ Best Practices
Resource Management
• Prefer smart pointers (unique_ptr / shared_ptr) over raw new/delete.
• Follow RAII — every resource acquisition ties to an object lifetime.
• Implement the Rule of Zero: if your class does not manage resources, let the compiler generate all
special members.
• Mark move constructors and move assignment operators noexcept.
Type Safety
• Prefer nullptr over NULL or 0 for null pointers.
• Use std::optional instead of sentinel values (-1, nullptr) to express "no value".
• Use std::variant instead of union for type-safe alternatives.
• Use enum class instead of plain enum to avoid implicit conversions.
Performance
• Pass large objects by const reference; use std::move when transferring ownership.
• Use std::vector as the default container — it is cache-friendly and fast.
• Reserve capacity (vector::reserve) when the size is known in advance.
• Profile before optimising: use perf, callgrind, or Tracy.
Code Quality
• Enable -Wall -Wextra -pedantic -Wshadow -Wconversion and treat warnings as errors.
• Use static analysers: clang-tidy, cppcheck, PVS-Studio.
• Format consistently with clang-format; commit a .clang-format file.
• Write unit tests with Google Test, Catch2, or doctest.
• Follow the C++ Core Guidelines ([Link]/CppCoreGuidelines).
C++ Guide Page 8 of 8