NexusCS

C++

Languages
Quick reference for modern C++ (C++11 through C++23) covering STL containers, smart pointers, move semantics, and templates.
cpp
c++
programming

Getting started

Introduction

Modern C++ (C++11/14/17/20/23) with STL, smart pointers, and move semantics.

Hello World

#include <iostream>

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

Compile: g++ -std=c++20 main.cpp -o main

Basic Types

// Integers
int x = 42;
long long y = 1000000LL;
unsigned int z = 100u;

// Floating point
float f = 3.14f;
double d = 3.14159;

// Boolean
bool flag = true;

// Character
char c = 'A';

// Auto type deduction (C++11)
auto a = 42;        // int
auto b = 3.14;      // double
auto c = "hello";   // const char*

Variables

// Declaration
int x;

// Initialization
int y = 10;
int z(10);
int w{10};  // Uniform initialization (C++11)

// Constants
const int MAX = 100;
constexpr int SIZE = 50;  // Compile-time constant

// References
int& ref = x;

// Pointers
int* ptr = &x;

Operators

| Operator | Description | | ------------------- | ------------------- | ------- | ------- | | + - * / | Arithmetic | | % | Modulo | | ++ -- | Increment/Decrement | | == != < > | Comparison | | <= >= | Comparison | | && | | ! | Logical | | & | ^ ~ | Bitwise | | << >> | Bit shift | | = | Assignment | | += -= *= /= | Compound assignment |

Control Flow

If Statement

if (x > 0) {
    // positive
} else if (x < 0) {
    // negative
} else {
    // zero
}

// If with initializer (C++17)
if (auto it = map.find(key); it != map.end()) {
    // use it
}

Switch Statement

switch (value) {
    case 1:
        // code
        break;
    case 2:
    case 3:
        // multiple cases
        break;
    default:
        // default case
        break;
}

// Switch with initializer (C++17)
switch (auto val = getValue(); val) {
    case 1: break;
    default: break;
}

Loops

// For loop
for (int i = 0; i < 10; ++i) {
    // code
}

// Range-based for (C++11)
std::vector<int> vec = {1, 2, 3};
for (const auto& item : vec) {
    // code
}

// While loop
while (condition) {
    // code
}

// Do-while loop
do {
    // code
} while (condition);

Loop Control

// Break - exit loop
for (int i = 0; i < 10; ++i) {
    if (i == 5) break;
}

// Continue - skip iteration
for (int i = 0; i < 10; ++i) {
    if (i % 2 == 0) continue;
}

Functions

Basic Functions

// Declaration
int add(int a, int b);

// Definition
int add(int a, int b) {
    return a + b;
}

// Inline function
inline int square(int x) {
    return x * x;
}

// Default parameters
void print(int x, int y = 0) {
    std::cout << x << " " << y;
}

Function Overloading

int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

// Different number of parameters
int add(int a, int b, int c) {
    return a + b + c;
}

Lambda Functions

// Basic lambda (C++11)
auto lambda = []() {
    std::cout << "Hello";
};

// With parameters
auto add = [](int a, int b) {
    return a + b;
};

// Capture by value
int x = 10;
auto f1 = [x]() { return x; };

// Capture by reference
auto f2 = [&x]() { x++; };

// Capture all by value
auto f3 = [=]() { return x; };

// Capture all by reference
auto f4 = [&]() { x++; };

// Generic lambda (C++14)
auto f5 = [](auto a, auto b) {
    return a + b;
};

Function Templates

// Function template
template<typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

// Usage
int i = max(10, 20);
double d = max(3.14, 2.72);

// Multiple type parameters
template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
    return a + b;
}

// Abbreviated function template (C++20)
auto add(auto a, auto b) {
    return a + b;
}

Classes & Objects

Basic Class

class Rectangle {
public:
    // Constructor
    Rectangle(int w, int h)
        : width(w), height(h) {}

    // Member function
    int area() const {
        return width * height;
    }

    // Getter
    int getWidth() const { return width; }

    // Setter
    void setWidth(int w) { width = w; }

private:
    int width;
    int height;
};

// Usage
Rectangle rect(10, 20);
int a = rect.area();

Constructors

class MyClass {
public:
    // Default constructor
    MyClass() = default;

    // Parameterized constructor
    MyClass(int x) : value(x) {}

    // Copy constructor
    MyClass(const MyClass& other)
        : value(other.value) {}

    // Move constructor (C++11)
    MyClass(MyClass&& other) noexcept
        : value(std::move(other.value)) {}

    // Delegating constructor (C++11)
    MyClass() : MyClass(0) {}

private:
    int value;
};

Destructor

class Resource {
public:
    Resource() {
        // Acquire resource
        ptr = new int[100];
    }

    ~Resource() {
        // Release resource
        delete[] ptr;
    }

private:
    int* ptr;
};

Inheritance

class Animal {
public:
    virtual void speak() const {
        std::cout << "Some sound";
    }

    virtual ~Animal() = default;
};

class Dog : public Animal {
public:
    void speak() const override {
        std::cout << "Woof!";
    }
};

// Usage
Animal* animal = new Dog();
animal->speak();  // "Woof!"
delete animal;

Access Specifiers

Specifier Description
public Accessible from anywhere
protected Accessible from class and derived classes
private Accessible only from class

Special Members

class MyClass {
public:
    // Default constructor
    MyClass() = default;

    // Copy constructor
    MyClass(const MyClass&) = default;

    // Copy assignment
    MyClass& operator=(const MyClass&) = default;

    // Move constructor (C++11)
    MyClass(MyClass&&) = default;

    // Move assignment (C++11)
    MyClass& operator=(MyClass&&) = default;

    // Destructor
    ~MyClass() = default;

    // Delete copy constructor
    MyClass(const MyClass&) = delete;
};

Templates

Class Templates

template<typename T>
class Stack {
public:
    void push(const T& item) {
        items.push_back(item);
    }

    T pop() {
        T item = items.back();
        items.pop_back();
        return item;
    }

    bool empty() const {
        return items.empty();
    }

private:
    std::vector<T> items;
};

// Usage
Stack<int> intStack;
intStack.push(10);
int x = intStack.pop();

Template Specialization

// Primary template
template<typename T>
class MyClass {
public:
    void print() {
        std::cout << "Generic";
    }
};

// Full specialization
template<>
class MyClass<int> {
public:
    void print() {
        std::cout << "Integer";
    }
};

// Partial specialization
template<typename T>
class MyClass<T*> {
public:
    void print() {
        std::cout << "Pointer";
    }
};

Variadic Templates

// C++11 variadic templates
template<typename... Args>
void print(Args... args) {
    (std::cout << ... << args) << '\n';  // C++17 fold expression
}

// Recursive variadic template
template<typename T>
void printRecursive(T value) {
    std::cout << value << '\n';
}

template<typename T, typename... Args>
void printRecursive(T first, Args... rest) {
    std::cout << first << ", ";
    printRecursive(rest...);
}

// Usage
print(1, 2, 3, "hello");

Concepts (C++20)

// Define concept
template<typename T>
concept Numeric = std::is_arithmetic_v<T>;

// Use concept
template<Numeric T>
T add(T a, T b) {
    return a + b;
}

// Concept with requires
template<typename T>
concept Addable = requires(T a, T b) {
    { a + b } -> std::convertible_to<T>;
};

STL Containers

Vector

#include <vector>

// Declaration
std::vector<int> vec;
std::vector<int> vec2 = {1, 2, 3};
std::vector<int> vec3(10);  // 10 elements
std::vector<int> vec4(10, 5);  // 10 elements, all 5

// Operations
vec.push_back(10);
vec.pop_back();
vec.insert(vec.begin(), 5);
vec.erase(vec.begin());
vec.clear();

// Access
int x = vec[0];
int y = vec.at(1);  // with bounds checking
int z = vec.front();
int w = vec.back();

// Size
size_t size = vec.size();
bool empty = vec.empty();
vec.resize(20);

Map

#include <map>

// Declaration
std::map<std::string, int> map;

// Operations
map["key"] = 42;
map.insert({"key2", 100});
map.erase("key");

// Access
int value = map["key"];
auto it = map.find("key");
if (it != map.end()) {
    int val = it->second;
}

// Iteration
for (const auto& [key, value] : map) {
    // C++17 structured bindings
}

Unordered Map

#include <unordered_map>

// Faster lookup than map (O(1) vs O(log n))
std::unordered_map<std::string, int> umap;

umap["key"] = 42;
auto it = umap.find("key");

// Check existence
if (umap.count("key") > 0) {
    // exists
}

// C++20 contains
if (umap.contains("key")) {
    // exists
}

Set

#include <set>

// Declaration
std::set<int> set;
std::set<int> set2 = {1, 2, 3};

// Operations
set.insert(10);
set.erase(10);
set.clear();

// Check membership
if (set.count(10) > 0) {
    // exists
}

// C++20 contains
if (set.contains(10)) {
    // exists
}

// Iteration (sorted order)
for (const auto& item : set) {
    // process item
}

Other Containers

#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <array>

// Deque (double-ended queue)
std::deque<int> deque;
deque.push_front(1);
deque.push_back(2);

// List (doubly-linked list)
std::list<int> list;
list.push_front(1);
list.push_back(2);

// Queue
std::queue<int> queue;
queue.push(1);
int x = queue.front();
queue.pop();

// Stack
std::stack<int> stack;
stack.push(1);
int y = stack.top();
stack.pop();

// Array (C++11)
std::array<int, 5> arr = {1, 2, 3, 4, 5};

STL Algorithms

Sorting & Searching

#include <algorithm>
#include <vector>

std::vector<int> vec = {3, 1, 4, 1, 5};

// Sort
std::sort(vec.begin(), vec.end());

// Sort with custom comparator
std::sort(vec.begin(), vec.end(),
    [](int a, int b) { return a > b; });

// Binary search (requires sorted)
bool found = std::binary_search(
    vec.begin(), vec.end(), 3);

// Find
auto it = std::find(vec.begin(), vec.end(), 4);
if (it != vec.end()) {
    // found
}

// Find with predicate
auto it2 = std::find_if(vec.begin(), vec.end(),
    [](int x) { return x > 3; });

Transformations

#include <algorithm>
#include <vector>

std::vector<int> vec = {1, 2, 3};
std::vector<int> result(3);

// Transform
std::transform(vec.begin(), vec.end(),
    result.begin(),
    [](int x) { return x * 2; });

// For each
std::for_each(vec.begin(), vec.end(),
    [](int x) { std::cout << x; });

// Copy
std::copy(vec.begin(), vec.end(),
    result.begin());

// Copy if
std::copy_if(vec.begin(), vec.end(),
    result.begin(),
    [](int x) { return x > 1; });

Numeric Operations

#include <numeric>
#include <vector>

std::vector<int> vec = {1, 2, 3, 4, 5};

// Sum (C++17)
int sum = std::accumulate(
    vec.begin(), vec.end(), 0);

// Product
int product = std::accumulate(
    vec.begin(), vec.end(), 1,
    std::multiplies<int>());

// Inner product
std::vector<int> vec2 = {1, 2, 3, 4, 5};
int dot = std::inner_product(
    vec.begin(), vec.end(),
    vec2.begin(), 0);

// Partial sum
std::vector<int> result(5);
std::partial_sum(vec.begin(), vec.end(),
    result.begin());

Other Algorithms

// Min/Max
int min = std::min(a, b);
int max = std::max(a, b);
auto [min, max] = std::minmax(a, b);  // C++17

// Min/Max element
auto it = std::min_element(vec.begin(), vec.end());
auto it2 = std::max_element(vec.begin(), vec.end());

// Count
int count = std::count(vec.begin(), vec.end(), 3);
int count2 = std::count_if(vec.begin(), vec.end(),
    [](int x) { return x > 2; });

// Reverse
std::reverse(vec.begin(), vec.end());

// Unique (remove consecutive duplicates)
auto last = std::unique(vec.begin(), vec.end());
vec.erase(last, vec.end());

Smart Pointers

unique_ptr

#include <memory>

// Create unique_ptr
auto ptr = std::make_unique<int>(42);

// Access
int value = *ptr;

// Release ownership
int* raw = ptr.release();

// Reset
ptr.reset(new int(100));

// Move ownership
auto ptr2 = std::move(ptr);
// ptr is now nullptr

// Custom deleter
auto deleter = [](int* p) {
    std::cout << "Deleting\n";
    delete p;
};
std::unique_ptr<int, decltype(deleter)>
    ptr3(new int(42), deleter);

shared_ptr

#include <memory>

// Create shared_ptr
auto ptr = std::make_shared<int>(42);

// Copy (increases reference count)
auto ptr2 = ptr;

// Reference count
long count = ptr.use_count();

// Access
int value = *ptr;

// Reset
ptr.reset();

// Create from unique_ptr
auto uptr = std::make_unique<int>(42);
std::shared_ptr<int> sptr = std::move(uptr);

weak_ptr

#include <memory>

// Create from shared_ptr
auto sptr = std::make_shared<int>(42);
std::weak_ptr<int> wptr = sptr;

// Check if expired
if (!wptr.expired()) {
    // Convert to shared_ptr
    if (auto locked = wptr.lock()) {
        int value = *locked;
    }
}

// Use count
long count = wptr.use_count();

// Reset
wptr.reset();

Raw Pointers

// Allocation
int* ptr = new int(42);
int* arr = new int[10];

// Deallocation
delete ptr;
delete[] arr;

// Null pointer (C++11)
int* ptr2 = nullptr;

// Check null
if (ptr2 == nullptr) {
    // is null
}

Move Semantics

Rvalue References

// Lvalue reference
int x = 10;
int& lref = x;

// Rvalue reference (C++11)
int&& rref = 10;
int&& rref2 = std::move(x);

// Forward reference (universal reference)
template<typename T>
void func(T&& arg) {
    // T can be lvalue or rvalue
}

Move Constructor

class MyClass {
public:
    // Move constructor
    MyClass(MyClass&& other) noexcept
        : data(other.data) {
        other.data = nullptr;
    }

    // Move assignment
    MyClass& operator=(MyClass&& other) noexcept {
        if (this != &other) {
            delete[] data;
            data = other.data;
            other.data = nullptr;
        }
        return *this;
    }

private:
    int* data;
};

std::move

#include <utility>

std::vector<int> v1 = {1, 2, 3};

// Move v1 into v2
std::vector<int> v2 = std::move(v1);
// v1 is now in valid but unspecified state

// Move into function
void func(std::vector<int> vec) {
    // vec owns the data
}
func(std::move(v2));

Perfect Forwarding

#include <utility>

template<typename T>
void wrapper(T&& arg) {
    // Forward arg preserving its value category
    func(std::forward<T>(arg));
}

// Usage
int x = 10;
wrapper(x);          // forwards as lvalue
wrapper(10);         // forwards as rvalue
wrapper(std::move(x)); // forwards as rvalue

RAII Pattern

Basic RAII

// Resource Acquisition Is Initialization
class FileHandle {
public:
    FileHandle(const std::string& filename) {
        file = fopen(filename.c_str(), "r");
        if (!file) {
            throw std::runtime_error("Failed to open");
        }
    }

    ~FileHandle() {
        if (file) {
            fclose(file);
        }
    }

    // Delete copy
    FileHandle(const FileHandle&) = delete;
    FileHandle& operator=(const FileHandle&) = delete;

private:
    FILE* file;
};

// Usage
{
    FileHandle handle("file.txt");
    // Use file
} // Automatically closed

Lock Guard

#include <mutex>

std::mutex mtx;

void func() {
    std::lock_guard<std::mutex> lock(mtx);
    // Critical section
    // Mutex automatically unlocked when lock goes out of scope
}

// Unique lock (more flexible)
void func2() {
    std::unique_lock<std::mutex> lock(mtx);
    // Can manually unlock
    lock.unlock();
    // Do something
    lock.lock();
}

Scope Guard

// Custom scope guard
template<typename Func>
class ScopeGuard {
public:
    explicit ScopeGuard(Func f)
        : func(std::move(f)), active(true) {}

    ~ScopeGuard() {
        if (active) func();
    }

    void dismiss() { active = false; }

    ScopeGuard(const ScopeGuard&) = delete;
    ScopeGuard& operator=(const ScopeGuard&) = delete;

private:
    Func func;
    bool active;
};

// Helper function
template<typename Func>
ScopeGuard<Func> makeScopeGuard(Func f) {
    return ScopeGuard<Func>(std::move(f));
}

// Usage
void func() {
    auto guard = makeScopeGuard([]() {
        std::cout << "Cleanup\n";
    });
    // Cleanup happens automatically
}

Modern C++ Features

C++11 Features

// Auto type deduction
auto x = 42;

// Range-based for
for (const auto& item : container) {}

// Lambda expressions
auto lambda = [](int x) { return x * 2; };

// nullptr
int* ptr = nullptr;

// Move semantics
std::vector<int> v2 = std::move(v1);

// Smart pointers
auto ptr = std::make_unique<int>(42);

// Uniform initialization
std::vector<int> vec{1, 2, 3};

// Variadic templates
template<typename... Args>
void func(Args... args) {}

// Static assertions
static_assert(sizeof(int) == 4, "Size error");

C++14 Features

// Generic lambdas
auto lambda = [](auto x, auto y) {
    return x + y;
};

// Return type deduction
auto add(int a, int b) {
    return a + b;
}

// Binary literals
int x = 0b1010;

// Digit separators
int y = 1'000'000;

// std::make_unique
auto ptr = std::make_unique<int>(42);

// Variable templates
template<typename T>
constexpr T pi = T(3.1415926535897932385);

C++17 Features

// Structured bindings
auto [x, y] = std::make_pair(1, 2);
auto [key, value] = *map.find("key");

// If with initializer
if (auto it = map.find(key); it != map.end()) {}

// Fold expressions
template<typename... Args>
auto sum(Args... args) {
    return (... + args);
}

// std::optional
std::optional<int> opt = 42;
if (opt.has_value()) {
    int value = *opt;
}

// std::variant
std::variant<int, double, std::string> var;
var = 42;
var = "hello";

// std::any
std::any any = 42;
any = std::string("hello");

C++20 Features

// Concepts
template<typename T>
concept Numeric = std::is_arithmetic_v<T>;

template<Numeric T>
T add(T a, T b) { return a + b; }

// Ranges
#include <ranges>
auto even = [](int x) { return x % 2 == 0; };
auto result = vec
    | std::views::filter(even)
    | std::views::transform([](int x) { return x * 2; });

// Three-way comparison (spaceship)
auto operator<=>(const MyClass&) const = default;

// Coroutines
#include <coroutine>
generator<int> fibonacci() {
    int a = 0, b = 1;
    while (true) {
        co_yield a;
        auto next = a + b;
        a = b;
        b = next;
    }
}

// Modules (experimental)
import std.core;

// consteval (compile-time only)
consteval int square(int x) {
    return x * x;
}

C++23 Features

// std::expected
std::expected<int, std::string> divide(int a, int b) {
    if (b == 0) {
        return std::unexpected("Division by zero");
    }
    return a / b;
}

// std::print (formatted output)
std::print("Hello, {}!\n", "World");
std::println("Value: {}", 42);

// Multidimensional subscript operator
class Matrix {
    auto operator[](int row, int col) const {
        return data[row][col];
    }
};

// if consteval
if consteval {
    // Compile-time code
} else {
    // Runtime code
}

// std::flat_map, std::flat_set
std::flat_map<int, std::string> map;

Common Idioms

Rule of Three

// If you define one, define all three:
// 1. Destructor
// 2. Copy constructor
// 3. Copy assignment operator

class MyClass {
public:
    // Destructor
    ~MyClass() {
        delete[] data;
    }

    // Copy constructor
    MyClass(const MyClass& other)
        : size(other.size) {
        data = new int[size];
        std::copy(other.data, other.data + size, data);
    }

    // Copy assignment
    MyClass& operator=(const MyClass& other) {
        if (this != &other) {
            delete[] data;
            size = other.size;
            data = new int[size];
            std::copy(other.data, other.data + size, data);
        }
        return *this;
    }

private:
    int* data;
    size_t size;
};

Rule of Five

// C++11: Add move constructor and move assignment
class MyClass {
public:
    ~MyClass() { delete[] data; }

    // Copy constructor
    MyClass(const MyClass& other)
        : size(other.size) {
        data = new int[size];
        std::copy(other.data, other.data + size, data);
    }

    // Copy assignment
    MyClass& operator=(const MyClass& other) {
        MyClass tmp(other);
        std::swap(data, tmp.data);
        std::swap(size, tmp.size);
        return *this;
    }

    // Move constructor
    MyClass(MyClass&& other) noexcept
        : data(other.data), size(other.size) {
        other.data = nullptr;
        other.size = 0;
    }

    // Move assignment
    MyClass& operator=(MyClass&& other) noexcept {
        if (this != &other) {
            delete[] data;
            data = other.data;
            size = other.size;
            other.data = nullptr;
            other.size = 0;
        }
        return *this;
    }

private:
    int* data;
    size_t size;
};

Rule of Zero

// Prefer using standard library types
// No need to define special member functions

class MyClass {
public:
    // Compiler-generated functions are fine
    // Use smart pointers and standard containers

private:
    std::vector<int> data;
    std::unique_ptr<Resource> resource;
    std::string name;
};

Copy-and-Swap

class MyClass {
public:
    // Copy constructor
    MyClass(const MyClass& other)
        : size(other.size) {
        data = new int[size];
        std::copy(other.data, other.data + size, data);
    }

    // Swap function
    friend void swap(MyClass& first, MyClass& second) noexcept {
        using std::swap;
        swap(first.data, second.data);
        swap(first.size, second.size);
    }

    // Copy assignment using copy-and-swap
    MyClass& operator=(MyClass other) {
        swap(*this, other);
        return *this;
    }

private:
    int* data;
    size_t size;
};

Compilation

GCC/G++

# Basic compilation
g++ main.cpp -o main

# C++ standard
g++ -std=c++20 main.cpp -o main

# Optimization levels
g++ -O0 main.cpp  # No optimization
g++ -O1 main.cpp  # Basic
g++ -O2 main.cpp  # Recommended
g++ -O3 main.cpp  # Aggressive

# Warnings
g++ -Wall -Wextra -Werror main.cpp

# Debug symbols
g++ -g main.cpp

# Include paths
g++ -I/path/to/headers main.cpp

# Link libraries
g++ main.cpp -lboost_system

# Multiple files
g++ file1.cpp file2.cpp -o program

Clang

# Basic compilation
clang++ main.cpp -o main

# C++ standard
clang++ -std=c++20 main.cpp -o main

# Optimization
clang++ -O2 main.cpp

# Warnings
clang++ -Wall -Wextra main.cpp

# Static analysis
clang++ --analyze main.cpp

# Address sanitizer
clang++ -fsanitize=address main.cpp

# Thread sanitizer
clang++ -fsanitize=thread main.cpp

CMake

# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(MyProject)

# C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Executable
add_executable(myapp main.cpp)

# Library
add_library(mylib lib.cpp)

# Link library
target_link_libraries(myapp mylib)

# Include directories
target_include_directories(myapp PRIVATE include)
# Build commands
mkdir build && cd build
cmake ..
cmake --build .

# Build type
cmake -DCMAKE_BUILD_TYPE=Debug ..
cmake -DCMAKE_BUILD_TYPE=Release ..

String Operations

std::string

#include <string>

// Declaration
std::string str = "Hello";
std::string str2("World");

// Concatenation
std::string result = str + " " + str2;
str += " World";

// Access
char c = str[0];
char c2 = str.at(1);

// Substring
std::string sub = str.substr(0, 5);

// Find
size_t pos = str.find("World");
if (pos != std::string::npos) {
    // found
}

// Replace
str.replace(0, 5, "Hi");

// Size
size_t len = str.length();
size_t size = str.size();

// Comparison
if (str == "Hello") {}
int cmp = str.compare("World");

String Views (C++17)

#include <string_view>

// Non-owning string reference
std::string_view sv = "Hello World";

// Efficient substring (no copy)
std::string_view sub = sv.substr(0, 5);

// Works with std::string
std::string str = "Hello";
std::string_view sv2 = str;

// Caution: lifetime issues
std::string_view dangling() {
    std::string temp = "Hello";
    return temp;  // Dangling reference!
}

String Conversion

#include <string>

// To string
std::string s1 = std::to_string(42);
std::string s2 = std::to_string(3.14);

// From string
int i = std::stoi("42");
long l = std::stol("1000000");
double d = std::stod("3.14");

// With error handling
size_t pos;
int x = std::stoi("42abc", &pos);
// pos is index of first invalid char

Exception Handling

Try-Catch

try {
    // Code that may throw
    throw std::runtime_error("Error occurred");
} catch (const std::runtime_error& e) {
    std::cerr << "Runtime error: " << e.what() << '\n';
} catch (const std::exception& e) {
    std::cerr << "Exception: " << e.what() << '\n';
} catch (...) {
    std::cerr << "Unknown exception\n";
}

Custom Exceptions

class MyException : public std::exception {
public:
    explicit MyException(const char* message)
        : msg(message) {}

    const char* what() const noexcept override {
        return msg.c_str();
    }

private:
    std::string msg;
};

// Usage
throw MyException("Something went wrong");

Standard Exceptions

#include <stdexcept>

// Logic errors
throw std::logic_error("Logic error");
throw std::invalid_argument("Invalid arg");
throw std::domain_error("Domain error");
throw std::length_error("Length error");
throw std::out_of_range("Out of range");

// Runtime errors
throw std::runtime_error("Runtime error");
throw std::range_error("Range error");
throw std::overflow_error("Overflow");
throw std::underflow_error("Underflow");

RAII and Exceptions

void func() {
    // RAII ensures cleanup on exception
    std::unique_ptr<Resource> res =
        std::make_unique<Resource>();

    // May throw
    riskyOperation();

    // Resource automatically cleaned up
    // even if exception is thrown
}

File I/O

Reading Files

#include <fstream>
#include <string>

// Read entire file
std::ifstream file("input.txt");
if (file.is_open()) {
    std::string line;
    while (std::getline(file, line)) {
        // Process line
    }
    file.close();
}

// Read word by word
std::ifstream file2("input.txt");
std::string word;
while (file2 >> word) {
    // Process word
}

// Read into string
std::ifstream file3("input.txt");
std::string content(
    (std::istreambuf_iterator<char>(file3)),
    std::istreambuf_iterator<char>()
);

Writing Files

#include <fstream>

// Write to file
std::ofstream file("output.txt");
if (file.is_open()) {
    file << "Hello, World!" << '\n';
    file << 42 << '\n';
    file.close();
}

// Append to file
std::ofstream file2("output.txt", std::ios::app);
file2 << "Appended text\n";

// Binary mode
std::ofstream file3("output.bin", std::ios::binary);
int data[] = {1, 2, 3, 4, 5};
file3.write(reinterpret_cast<char*>(data), sizeof(data));

File Status

#include <fstream>
#include <filesystem>

// Check if file exists (C++17)
namespace fs = std::filesystem;
if (fs::exists("file.txt")) {
    // exists
}

// File size
size_t size = fs::file_size("file.txt");

// Check if stream is open
std::ifstream file("input.txt");
if (!file.is_open()) {
    std::cerr << "Failed to open file\n";
}

// Check for errors
if (file.fail()) {
    // Error occurred
}

Also see