Modern C++ (C++11~C++20) Core Syntax Cheatsheet | auto·Lambda·Smart Pointers·Concepts at a Glance

Modern C++ (C++11~C++20) Core Syntax Cheatsheet | auto·Lambda·Smart Pointers·Concepts at a Glance

이 글의 핵심

Modern C++ C++11~C++20 core syntax cheatsheet. auto, range-for, lambda, smart pointers, optional, variant, Concepts, Ranges copy-paste ready summary.

Introduction

Modern C++ (C++11 onwards) introduced auto, lambda, smart pointers, optional, Concepts and many features. This guide is a cheatsheet compressing what’s really used daily in production for quick reference.

What You Will Learn

  • Grasp C++11~C++20 core syntax at a glance
  • Learn copy-paste ready patterns frequently used in production
  • Compare major features by version
  • Get code ready for coding tests and production

Table of Contents

  1. C++11: auto, range-for, lambda, smart pointers
  2. C++14: Generic lambda, make_unique
  3. C++17: Structured binding, optional, if constexpr
  4. C++20: Concepts, Ranges, Coroutine
  5. Real-World Cases
  6. Troubleshooting
  7. Conclusion

C++11: auto, range-for, lambda, smart pointers

1) auto - Type Deduction

auto x = 42;                    // int
auto d = 3.14;                  // double
auto s = std::string("hello");  // std::string
auto v = std::vector<int>{1, 2, 3};  // std::vector<int>
// Iterator
auto it = v.begin();
// Function return type
auto add(int a, int b) -> int {
    return a + b;
}

2) range-based for

std::vector<int> v = {1, 2, 3, 4, 5};
// Read
for (int x : v) {
    std::cout << x << std::endl;
}
// Modify
for (int& x : v) {
    x *= 2;
}
// const reference
for (const auto& x : v) {
    std::cout << x << std::endl;
}

3) Lambda Expression

// Basic
auto add = [](int a, int b) { return a + b; };
std::cout << add(2, 3) << std::endl;  // 5
// Capture
int factor = 10;
auto multiply = [factor](int x) { return x * factor; };
std::cout << multiply(5) << std::endl;  // 50
// Capture modes
[=]   // Capture by value
[&]   // Capture by reference
[x]   // Capture x by value only
[&x]  // Capture x by reference only

4) Smart Pointers

#include <memory>
// unique_ptr (single ownership)
auto p1 = std::make_unique<int>(42);
std::cout << *p1 << std::endl;
// shared_ptr (shared ownership)
auto p2 = std::make_shared<int>(42);
auto p3 = p2;  // Increment reference count
// weak_ptr (prevent circular reference)
std::weak_ptr<int> wp = p2;
if (auto sp = wp.lock()) {
    std::cout << *sp << std::endl;
}

5) nullptr

// C++98
int* p = NULL;  // Confusing with 0
// C++11
int* p = nullptr;  // Type-safe

6) Initializer List

std::vector<int> v = {1, 2, 3, 4, 5};
std::map<std::string, int> m = {{"a", 1}, {"b", 2}};

C++14: Generic lambda, make_unique

1) Generic Lambda

auto print = [](auto x) { std::cout << x << std::endl; };
print(42);
print("hello");
print(3.14);

2) make_unique

// C++11
std::unique_ptr<int> p(new int(42));
// C++14
auto p = std::make_unique<int>(42);

3) Return Type Deduction

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

C++17: Structured binding, optional, if constexpr

1) Structured Binding

// pair
std::pair<int, std::string> p = {1, "hello"};
auto [id, name] = p;
std::cout << id << ", " << name << std::endl;
// map
std::map<std::string, int> m = {{"a", 1}, {"b", 2}};
for (const auto& [key, value] : m) {
    std::cout << key << ": " << value << std::endl;
}
// tuple
std::tuple<int, double, std::string> t = {1, 3.14, "hello"};
auto [i, d, s] = t;

2) std::optional

#include <optional>
std::optional<int> find(const std::vector<int>& v, int target) {
    for (int x : v) {
        if (x == target) return x;
    }
    return std::nullopt;
}
auto result = find(v, 5);
if (result) {
    std::cout << "Found: " << *result << std::endl;
} else {
    std::cout << "Not found" << std::endl;
}
// value_or
int value = result.value_or(0);

3) std::variant

#include <variant>
std::variant<int, double, std::string> v;
v = 42;
std::cout << std::get<int>(v) << std::endl;
v = 3.14;
std::cout << std::get<double>(v) << std::endl;
v = "hello";
std::cout << std::get<std::string>(v) << std::endl;
// Visitor pattern
std::visit([](auto&& arg) {
    std::cout << arg << std::endl;
}, v);

4) if constexpr

template<typename T>
void process(T value) {
    if constexpr (std::is_integral_v<T>) {
        std::cout << "Integer: " << value << std::endl;
    } else if constexpr (std::is_floating_point_v<T>) {
        std::cout << "Float: " << value << std::endl;
    } else {
        std::cout << "Other: " << value << std::endl;
    }
}
process(42);      // Integer
process(3.14);    // Float
process("hello"); // Other

5) Class Template Argument Deduction

// C++14
std::pair<int, std::string> p(1, "hello");
// C++17
std::pair p(1, "hello");  // Type deduced
std::vector v{1, 2, 3};   // std::vector<int>

C++20: Concepts, Ranges, Coroutine

1) Concepts

#include <concepts>
template<std::integral T>
T add(T a, T b) {
    return a + b;
}
// Custom concept
template<typename T>
concept Addable = requires(T a, T b) {
    { a + b } -> std::convertible_to<T>;
};
template<Addable T>
T sum(T a, T b) {
    return a + b;
}

2) Ranges

#include <ranges>
#include <vector>
std::vector<int> v = {1, 2, 3, 4, 5};
// Filter even numbers
auto even = v | std::views::filter([](int x) { return x % 2 == 0; });
// Transform
auto doubled = v | std::views::transform([](int x) { return x * 2; });
// Chain
auto result = v 
    | std::views::filter([](int x) { return x % 2 == 0; })
    | std::views::transform([](int x) { return x * 2; });

3) Three-way Comparison Operator

#include <compare>
struct Point {
    int x, y;
    auto operator<=>(const Point&) const = default;
};
Point p1{1, 2};
Point p2{1, 3};
if (p1 < p2) {
    std::cout << "p1 < p2" << std::endl;
}

Troubleshooting

Problem 1: auto Overuse

Symptom: Code readability decreases

// ❌ Unclear type
auto x = 0;  // int? long? size_t?
// ✅ Explicit type
int x = 0;
// Good auto usage
auto it = v.begin();  // Iterator
auto lambda = [](int x) { return x * 2; };

Problem 2: Lambda Capture Dangling

Symptom: Lambda captures invalid reference

// ❌ Dangling reference
auto makeLambda() {
    int x = 42;
    return [&x]() { return x; };  // x disappears from stack
}
// ✅ Capture by value
auto makeLambda() {
    int x = 42;
    return [x]() { return x; };
}

Problem 3: shared_ptr Circular Reference

Symptom: Memory leak

#include <memory>
struct Node {
    std::shared_ptr<Node> next;
};
// ❌ Circular reference
auto n1 = std::make_shared<Node>();
auto n2 = std::make_shared<Node>();
n1->next = n2;
n2->next = n1;  // Circular reference (memory leak)
// ✅ Use weak_ptr
struct NodeFixed {
    std::weak_ptr<NodeFixed> next;
};

Problem 4: optional Value Access Without Check

Symptom: std::bad_optional_access exception

std::optional<int> opt;
// ❌ Access without check
// int x = *opt;  // Exception
// ✅ Check before access
if (opt) {
    int x = *opt;
}
// Or value_or
int x = opt.value_or(0);

Conclusion

Modern C++ greatly improves code quality and productivity.

Key Summary

  1. C++11
    • auto, range-for, lambda, smart pointers
    • nullptr, initializer list
  2. C++14
    • Generic lambda, make_unique
    • Return type deduction
  3. C++17
    • Structured binding, optional, variant
    • if constexpr, class template argument deduction
  4. C++20
    • Concepts, Ranges, Coroutine
    • Three-way comparison operator

Adoption Order

StageFeatureReason
Stage 1auto, range-for, smart pointersBug reduction
Stage 2lambda, optionalCode conciseness
Stage 3Structured binding, variantReadability
Stage 4Concepts, RangesExpressiveness

Core Features by Version

// C++11
auto x = 42;
for (auto& x : v) { /* ....*/ }
auto lambda = [](int x) { return x * 2; };
auto p = std::make_shared<int>(42);
// C++14
auto print = [](auto x) { std::cout << x; };
auto p = std::make_unique<int>(42);
// C++17
auto [key, value] = map.begin();
std::optional<int> opt = find(v, 5);
if constexpr (std::is_integral_v<T>) { /* ....*/ }
// C++20
template<std::integral T>
T add(T a, T b) { return a + b; }
auto even = v | std::views::filter([](int x) { return x % 2 == 0; });

Next Steps

  • auto and decltype: C++ auto and decltype
  • Range-based for: C++ Range-based for
  • C++ Overview: What is C++?

References

  • “Effective Modern C++” - Scott Meyers
  • “C++17 The Complete Guide” - Nicolai M. Josuttis
  • “C++20 The Complete Guide” - Nicolai M. Josuttis
  • cppreference: https://en.cppreference.com/ One-line summary: Modern C++ greatly improves code quality and productivity with auto, lambda, smart pointers, optional, and Concepts.