Free learning resource

Source code & resources

Every code example from Modern C++: From First Program to Concurrency and Templates — free to read, copy and run. No sign-up, no catch. If you found this from one of my courses, welcome; take the code and keep building.

Source code

Code from every lesson

32 examples, in lesson order.

1. Hello, World and the Anatomy of a Translation Unit C++

#include <iostream>

int main() {
    std::cout << "A wild Snorlax blocks the path!\n";
    return 0;
}

2. Variables, Initialization, and the Auto Keyword C++

#include <iostream>
#include <string>

int main() {
    // Copy init with the equals sign
    int hero_hp = 100;
    double mana_pool = 47.5;
    std::string hero_name = "Aria";

    std::cout << hero_name
              << " has " << hero_hp
              << " HP and "
              << mana_pool << " mana.\n";
    return 0;
}

3. The Fundamental Types and Their Sizes C++

#include <iostream>

int main() {
    std::cout << "int: " << sizeof(int)
              << " bytes\n";
    std::cout << "long: " << sizeof(long)
              << " bytes\n";
    std::cout << "long long: "
              << sizeof(long long)
              << " bytes\n";
    return 0;
}

4. Arithmetic, Comparison, and Logical Operators C++

#include <iostream>

int main() {
    int sword_dmg = 47;
    int magic_dmg = 23;

    int total = sword_dmg + magic_dmg;
    int diff = sword_dmg - magic_dmg;
    int combo = sword_dmg * 2;

    std::cout << "Total damage: "
              << total << "\n";
    std::cout << "Damage gap: "
              << diff << "\n";
    std::cout << "Combo strike: "
              << combo << "\n";
    return 0;
}

5. Strings, Concatenation, and Reading From the User C++

#include <iostream>
#include <string>

int main() {
    std::string hero = "Cloud";
    std::string weapon = "Buster Sword";

    std::cout << hero << std::endl;
    std::cout << "Wields: " << weapon
              << std::endl;
    return 0;
}

6. If, Else If, and the Ternary Operator C++

#include <iostream>

int main() {
    int hero_hp = 25;

    if (hero_hp < 30) {
        std::cout << "Warning! Low HP!\n";
    }

    std::cout << "HP left: " << hero_hp
              << "\n";
    return 0;
}

7. The Switch Statement and Fallthrough C++

#include <iostream>

int main() {
    int day = 3;

    switch (day) {
        case 1:
            std::cout << "Monday Mayhem!\n";
            break;
        case 2:
            std::cout << "Tuesday Treasure!\n";
            break;
        case 3:
            std::cout << "Wednesday Warzone!\n";
            break;
        default:
            std::cout << "Rest day!\n";
    }
    return 0;
}

8. While and Do-While Loops C++

#include <iostream>
using namespace std;

int main() {
    double mana = 256.0;

    while (mana >= 1.0) {
        cout << "Mana left: " << mana << "\n";
        mana = mana / 2.0;
    }

    cout << "Mana depleted!\n";
    return 0;
}

9. The For Loop and the Range-Based For C++

#include <iostream>

int main() {
    int total_xp = 0;

    // Sum XP from levels one to ten
    for (int level = 1; level <= 10; ++level) {
        total_xp += level * 10;
    }

    std::cout << "Total XP: "
              << total_xp << "\n";
    return 0;
}

10. Break, Continue, and Early Exit C++

#include <iostream>
using namespace std;

int main() {
    cout << "Opening loot chests!\n";
    for (int drop = 1; drop <= 10; ++drop) {
        if (drop % 3 == 0) {
            cout << "Chest " << drop;
            cout << ": cursed, skipping!\n";
            continue;
        }
        cout << "Chest " << drop;
        cout << ": gold coins!\n";
    }
    return 0;
}

11. Declaring and Calling Functions C++

#include <iostream>

// Adds two damage rolls together
int totalDamage(int swordHit, int spellHit) {
    return swordHit + spellHit;
}

int main() {
    int combo = totalDamage(25, 40);
    std::cout << "Combo damage: "
              << combo << "\n";
    return 0;
}

12. Pass by Value, Reference, and Const Reference C++

#include <iostream>
#include <string>

void rename_hero(std::string name) {
    name = "Shadow " + name;
    std::cout << "Inside: " << name
              << "\n";
}

int main() {
    std::string hero = "Cloud";
    rename_hero(hero);
    std::cout << "Outside: " << hero
              << "\n";
    return 0;
}

13. Default Arguments and Function Overloading C++

#include <iostream>
#include <string>

void greet(std::string hero,
           std::string call = "Welcome") {
    std::cout << call << ", "
              << hero << "!"
              << std::endl;
}

int main() {
    greet("Link");
    greet("Zelda", "Hail");
    return 0;
}

14. Lambdas: Functions That Travel C++

#include <iostream>

int main() {
    auto crit_hit = [](int base) {
        return base * 3;
    };

    int sword_damage = 25;
    int bow_damage = 18;

    std::cout << "Sword crit: "
              << crit_hit(sword_damage)
              << "\n";
    std::cout << "Bow crit: "
              << crit_hit(bow_damage)
              << "\n";
    return 0;
}

15. Scope, Lifetime, and Why Local Pointers Bite C++

#include <iostream>
int main() {
    int score = 100;
    std::cout << "Outer score: "
              << score << "\n";

    for (int i = 0; i < 3; ++i) {
        int score = 50;
        score += i * 10;
        std::cout << "Inner: "
                  << score << "\n";
    }

    std::cout << "Outer still: "
              << score << "\n";
    return 0;
}

16. C-Style Arrays and std::array C++

#include <iostream>

int main() {
    int loot[5] = {120, 85, 200, 45, 175};

    for (int i = 0; i < 5; i++) {
        std::cout << "Drop " << i + 1;
        std::cout << " gold: " << loot[i] << "\n";
    }

    return 0;
}

17. std::vector: The Default Container C++

#include <iostream>
#include <vector>

int main() {
    std::vector<int> loot;

    loot.push_back(50);
    loot.push_back(120);
    loot.push_back(75);
    loot.push_back(200);
    loot.push_back(33);

    std::cout << "First drop: "
              << loot[0]
              << " gold\n";
    std::cout << "Total drops: "
              << loot.size()
              << "\n";
    return 0;
}

18. std::map and std::unordered_map C++

#include <iostream>
#include <map>
#include <string>

int main() {
    // Map from hero name to level
    std::map<std::string, int> party = {
        {"Cloud", 50},
        {"Aerith", 47},
        {"Tifa", 49}
    };

    std::cout << "Party size: "
              << party.size() << "\n";
    std::cout << "Cloud is level "
              << party["Cloud"] << "\n";
    return 0;
}

19. Tuples, Pairs, and Structured Bindings C++

#include <iostream>
#include <utility>
#include <string>

int main() {
    std::pair<std::string, int> hero{"Zelda", 100};

    std::cout << hero.first
              << " has HP "
              << hero.second << "\n";

    hero.first = "Link";
    hero.second = 250;
    std::cout << hero.first
              << " powered up to "
              << hero.second << " HP!\n";
    return 0;
}

20. Iterators and the Algorithm Library C++

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> dragon_hp =
        {450, 120, 800, 230, 95};

    std::sort(dragon_hp.begin(),
              dragon_hp.end());

    std::cout << "Sorted dragon HP: ";
    for (int hp : dragon_hp) {
        std::cout << hp << " ";
    }
    std::cout << "\n";
    return 0;
}

21. Threads and Joinable Workers C++

#include <iostream>
#include <thread>

void quest() {
    std::cout << "Hero raids dungeon\n";
}

int main() {
    std::thread hero(quest);
    hero.join();
    std::cout << "Quest complete\n";
    return 0;
}

22. Mutexes, Lock Guards, and the Race Condition C++

#include <iostream>
#include <thread>

int gold = 0;

void mine() {
    for (int i = 0; i < 100000; ++i) {
        gold = gold + 1;
    }
}

int main() {
    std::thread t1(mine);
    std::thread t2(mine);
    t1.join();
    t2.join();
    std::cout << "Gold mined: " << gold << "\n";
    return 0;
}

23. std::async, Futures, and Returning Values C++

#include <iostream>
#include <future>

long long sum_xp() {
    long long total = 0;
    for (int i = 1;
         i <= 10000000; ++i) {
        total += i;
    }
    return total;
}

int main() {
    std::future<long long> f =
        std::async(sum_xp);

    long long xp = f.get();
    std::cout << "Total XP: ";
    std::cout << xp << "\n";
}

24. Atomic Operations and Lock-Free Counters C++

#include <iostream>
#include <thread>

int loot_count = 0;

void grab_loot() {
    for (int i = 0; i < 100000; i++) {
        loot_count++;
    }
}

int main() {
    std::thread t1(grab_loot);
    std::thread t2(grab_loot);
    t1.join();
    t2.join();
    std::cout << "Loot grabbed: "
              << loot_count << "\n";
    return 0;
}

25. Smart Pointers: unique_ptr, shared_ptr, and weak_ptr C++

#include <iostream>
#include <memory>
#include <string>

struct Hero {
    std::string name;
    int hp;
};

int main() {
    auto link = std::make_unique<Hero>(
        Hero{"Link", 100}
    );
    std::cout << link->name
              << " has "
              << link->hp << " HP!\n";
    return 0;
}

26. Exception Safety and the Stack Unwind C++

#include <iostream>
#include <stdexcept>

void cast_meteor(int mana) {
    if (mana < 50) {
        throw std::runtime_error(
            "Wand fizzled!");
    }
    std::cout << "Meteor lands!\n";
}

int main() {
    try {
        cast_meteor(20);
    } catch (const std::exception& e) {
        std::cout << "Caught: "
                  << e.what() << "\n";
    }
}

27. Function Templates and Type Deduction C++

#include <iostream>

template <typename T>
T pick_stronger(T hero_a, T hero_b) {
    return (hero_a > hero_b)
        ? hero_a : hero_b;
}

28. Class Templates and the STL Mindset C++

#include <iostream>
#include <string>
#include <vector>

template <typename T>
class Box {
public:
    Box(T v) : stored(v) {}

    T get() const {
        return stored;
    }

private:
    T stored;
};

29. Concepts: Constraining Templates Readably C++

#include <iostream>

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

int main() {
    int hero_dmg = 47;
    int boss_dmg = 62;
    std::cout << "Boss strikes harder: "
              << pick_winner(hero_dmg, boss_dmg)
              << " damage!\n";
    return 0;
}

30. Ranges and Pipeline-Style Algorithms C++

#include <iostream>
#include <vector>

int main() {
    std::vector<int> xp_drops = {
        3, 8, 5, 12, 7, 4, 10, 9, 2, 6
    };

    int total = 0;
    int taken = 0;

    for (int xp : xp_drops) {
        if (xp % 2 != 0) continue;
        int squared = xp * xp;
        total += squared;
        taken++;
        if (taken == 5) break;
    }

    std::cout << "Total XP: " << total;
    std::cout << "\n";
    return 0;
}

31. std::variant, std::optional, and Sum Types C++

#include <iostream>
#include <optional>
#include <string>

std::optional<std::string> findHero(int id) {
    if (id == 1) return "Pikachu";
    if (id == 2) return "Charizard";
    return std::nullopt;
}

int main() {
    auto hero = findHero(2);
    if (hero.has_value()) {
        std::cout << "Found: " << *hero << "\n";
    } else {
        std::cout << "No hero in roster.\n";
    }
}

32. constexpr and Compile-Time Evaluation C++

#include <iostream>

constexpr int factorial(int n) {
    if (n <= 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

int main() {
    constexpr int combos = factorial(5);
    std::cout << "Spell combos at rank 5: "
              << combos << "\n";
    return 0;
}