| seoTitle | C++ Programming Reference – Modern C++ Syntax and Features |
|---|---|
| description | Comprehensive C++ reference covering STL, templates, smart pointers, lambdas, move semantics, C++11/14/17/20 features, and object-oriented programming patterns. |
| keywords | cpp, C++ programming, C++ reference, STL, templates, smart pointers, lambdas, move semantics, C++17, C++20, object-oriented, modern C++, cpp notes, cpp cheatsheet, cpp guide, c++ tutorial, VR-Rathod, Code-Note, code note vr, vr book |
| displayTitle | C++ |
- How:
- Developed by Bjarne Stroustrup in 1979 at Bell Labs.
- Originally called "C with Classes", renamed to C++ in 1983.
- Evolved through major standards: C++98, C++03, C++11, C++14, C++17, C++20, C++23.
- Who:
- Bjarne Stroustrup — creator of C++, computer scientist at Bell Labs / AT&T.
- Why:
- To add object-oriented programming to C while keeping its raw performance.
- To support both low-level system programming and high-level application development.
- To introduce abstractions (classes, templates, RAII) without sacrificing speed.
-
-
collapsed:: true
- Performance & Control — Direct memory access via pointers, zero-cost abstractions, ideal for games, OS, embedded systems.
- Multi-Paradigm — Supports procedural, object-oriented, and generic programming (templates).
- STL — Rich standard library: vectors, maps, algorithms, iterators.
- RAII — Resource Acquisition Is Initialization ensures safe resource management.
- Compatibility with C — Can integrate legacy C code directly.
- Cross-Platform — Compiles on Linux, Windows, macOS, embedded targets.
-
collapsed:: true
- Complex Syntax — Steeper learning curve than Python or Java.
- Manual Memory Management — Risk of memory leaks and segfaults without smart pointers.
- Long Compile Times — Heavy template usage can slow builds significantly.
- No Garbage Collection — Developer is responsible for memory lifecycle.
- Undefined Behavior — Many operations (out-of-bounds, null deref) are UB, not exceptions.
-
collapsed:: true
-
-
-
#include <iostream> int main() { std::cout << "Hello, World!" << std::endl; return 0; }
main()is the program entry point, returnsint(0 = success).#include <iostream>brings in the standard I/O stream library.
-
-
-
// Single line comment /* Multi-line comment */ /// Doxygen-style doc comment (used for documentation generation)
-
-
-
int age = 25; // Integer (4 bytes) float price = 9.99f; // Single precision float (4 bytes) double pi = 3.14159265; // Double precision float (8 bytes) char grade = 'A'; // Single character (1 byte) bool isActive = true; // Boolean (1 byte) std::string name = "VR bro"; // String (from <string>) // Constants const int MAX = 100; constexpr double TAX = 0.18; // Compile-time constant (C++11)
-
-
-
Type Size Range bool 1 byte true / false char 1 byte -128 to 127 int 4 bytes -2,147,483,648 to 2,147,483,647 long 8 bytes -9.2E18 to 9.2E18 float 4 bytes ~6-7 decimal digits precision double 8 bytes ~15-16 decimal digits precision long double 10/16 bytes extended precision wchar_t 2/4 bytes wide character
-
-
-
unsigned int u = 4294967295U; // no negative values short int s = 32767; // 2 bytes (16 bits) , range -32,768 to 32,767 long long ll = 9223372036854775807LL; unsigned long long ull = 18446744073709551615ULL;
-
-
-
auto x = 42; // int auto y = 3.14; // double auto z = "hello"; // const char* auto s = std::string("hi"); // std::string // decltype — deduce type from expression int a = 5; decltype(a) b = 10; // b is int
-
-
-
#include <iostream> #include <string> int main() { int num; std::string name; std::cout << "Enter a number: "; std::cin >> num; std::cout << "Enter your name: "; std::cin.ignore(); std::getline(std::cin, name); // reads full line with spaces std::cout << "Hello " << name << ", you entered " << num; }
-
-
collapsed:: true
-
// Arithmetic + - * / % // add, sub, mul, div, modulo ++x x++ // pre/post increment --x x-- // pre/post decrement // Relational == != < > <= >= // Logical && || ! // Bitwise & | ^ ~ << >> // Assignment = += -= *= /= %= &= |= ^= <<= >>= // Ternary int max = (a > b) ? a : b; // sizeof std::cout << sizeof(int); // 4
-
-
collapsed:: true
-
// C-style (avoid in modern C++) double d = (double)5 / 2; // C++ style casts (preferred) int i = static_cast<int>(3.99); // 3 — safe compile-time cast Base* b = new Derived(); Derived* d = dynamic_cast<Derived*>(b); // safe runtime downcast (needs RTTI) const int ci = 5; int* p = const_cast<int*>(&ci); // removes const (use carefully) int* ip = reinterpret_cast<int*>(0xDEAD); // low-level bit reinterpretation
-
-
-
collapsed:: true
-
collapsed:: true
-
int score = 85; if (score >= 90) { std::cout << "A"; } else if (score >= 80) { std::cout << "B"; } else if (score >= 70) { std::cout << "C"; } else { std::cout << "F"; } // Output: B
-
-
collapsed:: true
-
int day = 3; switch (day) { case 1: std::cout << "Monday"; break; case 2: std::cout << "Tuesday"; break; case 3: std::cout << "Wednesday"; break; default: std::cout << "Other"; break; }
-
-
collapsed:: true
-
// condition ? if_true : if_false int max = (a > b) ? a : b; std::string label = (age >= 18) ? "Adult" : "Minor";
-
-
collapsed:: true
-
// for loop for (int i = 0; i < 5; i++) { std::cout << i << " "; } // Output: 0 1 2 3 4 // while loop int i = 0; while (i < 5) { std::cout << i++; } // do-while (executes at least once) int n = 0; do { std::cout << n++; } while (n < 3); // range-based for (C++11) std::vector<int> nums = {1, 2, 3, 4, 5}; for (int n : nums) { std::cout << n << " "; } // range-based with auto & reference (efficient for large objects) for (const auto& n : nums) { std::cout << n << " "; }
-
-
collapsed:: true
-
for (int i = 0; i < 10; i++) { if (i == 3) continue; // skip 3 if (i == 7) break; // stop at 7 std::cout << i << " "; } // Output: 0 1 2 4 5 6 // goto (avoid in modern code, but valid) goto end; std::cout << "skipped"; end: std::cout << "reached end";
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <iostream> int add(int a, int b); // declaration (prototype) int main() { std::cout << add(3, 4); // calling → 7 } int add(int a, int b) { // definition return a + b; }
-
-
collapsed:: true
-
void greet(std::string name, std::string msg = "Hello") { std::cout << msg << ", " << name; } greet("Alice"); // Hello, Alice greet("Bob", "Hi"); // Hi, Bob
-
-
collapsed:: true
-
int area(int side) { return side * side; } int area(int w, int h) { return w * h; } double area(double r) { return 3.14159 * r * r; } std::cout << area(5); // 25 std::cout << area(3, 4); // 12 std::cout << area(2.0); // 12.566...
-
-
collapsed:: true
-
void byValue(int x) { x = 99; } // original unchanged void byRef(int& x) { x = 99; } // original changed void byPtr(int* x) { *x = 99; } // original changed via pointer int n = 5; byValue(n); // n = 5 byRef(n); // n = 99 byPtr(&n); // n = 99
-
-
collapsed:: true
-
// Hint to compiler to expand function body at call site (avoids call overhead) inline int square(int x) { return x * x; } std::cout << square(5); // 25
-
-
collapsed:: true
-
int factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); } std::cout << factorial(5); // 120
-
-
collapsed:: true
-
// [capture](params) -> return_type { body } auto add = [](int a, int b) { return a + b; }; std::cout << add(3, 4); // 7 int x = 10; auto addX = [x](int n) { return n + x; }; // capture by value auto addXRef = [&x](int n) { x += n; }; // capture by reference // capture all by value [=], all by ref [&] auto all = [=]() { return x * 2; }; // used with STL algorithms std::vector<int> v = {3, 1, 4, 1, 5}; std::sort(v.begin(), v.end(), [](int a, int b) { return a > b; }); // v = {5, 4, 3, 1, 1}
-
-
collapsed:: true
-
#include <functional> // Function pointer int (*fp)(int, int) = add; std::cout << fp(2, 3); // 5 // std::function — wraps any callable std::function<int(int, int)> fn = add; fn = [](int a, int b) { return a * b; }; std::cout << fn(3, 4); // 12
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
int val = 42; int* ptr = &val; // ptr holds address of val std::cout << val; // 42 — value std::cout << &val; // 0x... — address std::cout << ptr; // 0x... — same address std::cout << *ptr; // 42 — dereference (value at address) *ptr = 99; // modifies val through pointer std::cout << val; // 99
-
-
collapsed:: true
-
int arr[] = {10, 20, 30, 40}; int* p = arr; std::cout << *p; // 10 std::cout << *(p+1); // 20 std::cout << *(p+2); // 30 p++; // move to next element std::cout << *p; // 20
-
-
collapsed:: true
-
int* p = nullptr; // preferred over NULL or 0 in modern C++ if (p != nullptr) { std::cout << *p; } else { std::cout << "null pointer"; }
-
-
collapsed:: true
-
int a = 10; int& ref = a; // ref is an alias for a ref = 20; // a is now 20 std::cout << a; // 20 // References vs Pointers: // - References cannot be null, pointers can // - References cannot be reassigned, pointers can // - References are safer and cleaner for most use cases
-
-
collapsed:: true
-
int x = 5, y = 10; const int* p1 = &x; // pointer to const — can't change *p1 int* const p2 = &x; // const pointer — can't change p2 itself const int* const p3 = &x; // both const // p1 = &y; ✓ (can change where it points) // *p1 = 9; ✗ (can't change value) // p2 = &y; ✗ (can't change pointer) // *p2 = 9; ✓ (can change value)
-
-
collapsed:: true
-
// Allocate single value int* p = new int(42); std::cout << *p; // 42 delete p; // free memory p = nullptr; // good practice // Allocate array int* arr = new int[5]{1, 2, 3, 4, 5}; std::cout << arr[2]; // 3 delete[] arr; // must use delete[] for arrays // Prefer smart pointers over raw new/delete in modern C++
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
int marks[5] = {92, 87, 95, 78, 88}; std::cout << marks[0]; // 92 marks[1] = 99; // size of array int size = sizeof(marks) / sizeof(marks[0]); // 5 // 2D array int grid[2][3] = {{1, 2, 3}, {4, 5, 6}}; std::cout << grid[1][2]; // 6
-
-
collapsed:: true
-
#include <array> std::array<int, 5> arr = {1, 2, 3, 4, 5}; std::cout << arr[0]; // 1 std::cout << arr.size(); // 5 std::cout << arr.front(); // 1 std::cout << arr.back(); // 5 arr.fill(0); // set all to 0 // iterate for (const auto& x : arr) std::cout << x << " ";
-
-
collapsed:: true
-
#include <string> std::string s = "Hello, World!"; std::cout << s.length(); // 13 std::cout << s.size(); // 13 (same as length) std::cout << s[0]; // H std::cout << s.substr(7, 5); // World std::cout << s.find("World"); // 7 s += " C++"; // concatenation s.replace(7, 5, "C++"); // replace "World" with "C++" s.erase(5, 2); // erase 2 chars at index 5 // convert int n = std::stoi("42"); // string to int std::string str = std::to_string(99); // int to string // compare if (s == "Hello") { ... } if (s.compare("Hello") == 0) { ... } // empty check if (s.empty()) { ... }
-
-
collapsed:: true
-
#include <string_view> void print(std::string_view sv) { std::cout << sv; // no copy made } std::string s = "Hello"; print(s); // works with std::string print("World"); // works with string literals
-
-
collapsed:: true
-
- [[DSA Algo & System Design]] - visit this page for in-depth Learning
-
collapsed:: true
-
class Car { public: std::string brand; int year; void display() { std::cout << brand << " (" << year << ")\n"; } }; Car c; c.brand = "Toyota"; c.year = 2022; c.display(); // Toyota (2022)
-
-
collapsed:: true
-
class Person { public: std::string name; int age; // Default constructor Person() : name("Unknown"), age(0) {} // Parameterized constructor Person(std::string n, int a) : name(n), age(a) {} // Copy constructor Person(const Person& other) : name(other.name), age(other.age) {} // Destructor ~Person() { std::cout << name << " destroyed\n"; } void show() { std::cout << name << ", " << age << "\n"; } }; Person p1("Alice", 30); Person p2 = p1; // copy constructor p1.show(); // Alice, 30
-
-
collapsed:: true
-
class BankAccount { public: std::string owner; // accessible everywhere protected: double balance; // accessible in class + subclasses private: std::string pin; // accessible only inside this class };
-
-
collapsed:: true
-
class Temperature { private: double celsius; public: void setCelsius(double c) { if (c >= -273.15) celsius = c; } double getCelsius() const { return celsius; } double getFahrenheit() const { return celsius * 9.0/5.0 + 32; } }; Temperature t; t.setCelsius(100); std::cout << t.getFahrenheit(); // 212
-
-
collapsed:: true
-
class Counter { public: static int count; // shared across all instances Counter() { count++; } ~Counter() { count--; } static int getCount() { return count; } // static method }; int Counter::count = 0; // must define outside class Counter a, b, c; std::cout << Counter::getCount(); // 3
-
-
collapsed:: true
-
class Box { private: double width; public: Box(double w) : width(w) {} friend double getWidth(Box b); // friend function declaration }; double getWidth(Box b) { return b.width; // can access private member } Box b(5.5); std::cout << getWidth(b); // 5.5
-
-
collapsed:: true
-
class Vector2D { public: float x, y; Vector2D(float x, float y) : x(x), y(y) {} // Overload + Vector2D operator+(const Vector2D& other) const { return Vector2D(x + other.x, y + other.y); } // Overload << friend std::ostream& operator<<(std::ostream& os, const Vector2D& v) { return os << "(" << v.x << ", " << v.y << ")"; } }; Vector2D a(1, 2), b(3, 4); std::cout << a + b; // (4, 6)
-
-
collapsed:: true
-
collapsed:: true
-
class Animal { public: std::string name; Animal(std::string n) : name(n) {} void eat() { std::cout << name << " is eating\n"; } }; class Dog : public Animal { public: Dog(std::string n) : Animal(n) {} void bark() { std::cout << name << " says Woof!\n"; } }; Dog d("Rex"); d.eat(); // Rex is eating d.bark(); // Rex says Woof!
-
-
collapsed:: true
-
class Base { ... }; class PublicDerived : public Base { ... }; // public → public, protected → protected class ProtectedDerived : protected Base { ... }; // public → protected class PrivateDerived : private Base { ... }; // all → private
-
-
collapsed:: true
-
// Multi-level class A { public: void hello() { std::cout << "A\n"; } }; class B : public A {}; class C : public B {}; // C inherits from B which inherits from A C obj; obj.hello(); // A // Multiple inheritance class Flyable { public: void fly() { std::cout << "Flying\n"; } }; class Swimmable { public: void swim() { std::cout << "Swimming\n"; } }; class Duck : public Flyable, public Swimmable {}; Duck d; d.fly(); // Flying d.swim(); // Swimming
-
-
collapsed:: true
-
class A { public: int x = 1; }; class B : virtual public A {}; class C : virtual public A {}; class D : public B, public C {}; // only one copy of A D obj; std::cout << obj.x; // 1 — no ambiguity
-
-
collapsed:: true
-
class Shape { public: std::string color; Shape(std::string c) : color(c) { std::cout << "Shape created\n"; } }; class Circle : public Shape { public: double radius; Circle(std::string c, double r) : Shape(c), radius(r) { std::cout << "Circle created\n"; } }; Circle ci("red", 5.0); // Output: // Shape created // Circle created
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
class Shape { public: virtual double area() const { return 0; } // virtual virtual void draw() const { std::cout << "Drawing shape\n"; } virtual ~Shape() {} // always virtual destructor in base class }; class Circle : public Shape { double r; public: Circle(double r) : r(r) {} double area() const override { return 3.14159 * r * r; } void draw() const override { std::cout << "Drawing circle\n"; } }; class Rectangle : public Shape { double w, h; public: Rectangle(double w, double h) : w(w), h(h) {} double area() const override { return w * h; } void draw() const override { std::cout << "Drawing rectangle\n"; } }; // Polymorphic usage via base pointer Shape* s1 = new Circle(5); Shape* s2 = new Rectangle(4, 6); s1->draw(); // Drawing circle s2->draw(); // Drawing rectangle std::cout << s1->area(); // 78.539... delete s1; delete s2;
-
-
collapsed:: true
-
class Animal { public: virtual void sound() = 0; // pure virtual — makes class abstract virtual ~Animal() {} }; // Animal a; // ERROR — cannot instantiate abstract class class Dog : public Animal { public: void sound() override { std::cout << "Woof!\n"; } }; class Cat : public Animal { public: void sound() override { std::cout << "Meow!\n"; } }; Animal* a = new Dog(); a->sound(); // Woof! delete a;
-
-
collapsed:: true
-
class Base { public: virtual void foo() {} virtual void bar() {} }; class Derived : public Base { public: void foo() override {} // override — compiler checks it actually overrides void bar() override final {} // final — no further override allowed }; class Leaf : public Derived { // void bar() override {} // ERROR — bar is final };
-
-
collapsed:: true
- Each class with virtual functions has a vtable (virtual function table).
- Each object has a hidden vptr pointing to its class's vtable.
- At runtime, the correct function is looked up via the vtable — this is dynamic dispatch.
-
// Conceptually: // Circle vtable → { &Circle::area, &Circle::draw } // Rectangle vtable → { &Rectangle::area, &Rectangle::draw } Shape* s = new Circle(3); s->area(); // looks up Circle::area via vptr → vtable
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
// Rule of Three: if you define any of these, define all three: // destructor, copy constructor, copy assignment operator // Rule of Five (C++11): also define move constructor & move assignment class Buffer { int* data; size_t size; public: Buffer(size_t s) : size(s), data(new int[s]) {} ~Buffer() { delete[] data; } // destructor Buffer(const Buffer& o) : size(o.size), data(new int[o.size]) { std::copy(o.data, o.data + size, data); // copy constructor } Buffer& operator=(const Buffer& o) { // copy assignment if (this != &o) { delete[] data; size = o.size; data = new int[size]; std::copy(o.data, o.data + size, data); } return *this; } Buffer(Buffer&& o) noexcept : size(o.size), data(o.data) { // move constructor o.data = nullptr; o.size = 0; } Buffer& operator=(Buffer&& o) noexcept { // move assignment if (this != &o) { delete[] data; data = o.data; size = o.size; o.data = nullptr; o.size = 0; } return *this; } }; // Rule of Zero: use smart pointers/STL — no manual resource management needed
-
-
collapsed:: true
-
std::string a = "Hello"; std::string b = std::move(a); // moves a's data into b — no copy // a is now in valid but unspecified state // rvalue reference: T&& void process(std::string&& s) { std::cout << "moved: " << s; } process(std::move(b)); // std::move doesn't move — it casts to rvalue reference // actual move happens in move constructor/assignment
-
-
collapsed:: true
-
// Core C++ idiom: tie resource lifetime to object lifetime // Resource acquired in constructor, released in destructor class FileHandle { FILE* file; public: FileHandle(const char* path) { file = fopen(path, "r"); if (!file) throw std::runtime_error("Cannot open file"); } ~FileHandle() { if (file) fclose(file); // always released, even on exception } FILE* get() { return file; } }; { FileHandle f("data.txt"); // acquired // use f.get()... } // destructor called here — file closed automatically
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <memory> std::unique_ptr<int> p = std::make_unique<int>(42); std::cout << *p; // 42 // cannot copy, only move std::unique_ptr<int> p2 = std::move(p); // p is now nullptr // with custom class auto obj = std::make_unique<Person>("Alice", 30); obj->show(); // automatically deleted when out of scope — no delete needed
-
-
collapsed:: true
-
auto sp1 = std::make_shared<int>(100); auto sp2 = sp1; // both own the resource std::cout << sp1.use_count(); // 2 — reference count std::cout << *sp1; // 100 sp1.reset(); // sp1 releases ownership std::cout << sp2.use_count(); // 1 // resource deleted when last shared_ptr goes out of scope
-
-
collapsed:: true
-
// Breaks circular references between shared_ptrs auto sp = std::make_shared<int>(50); std::weak_ptr<int> wp = sp; std::cout << wp.use_count(); // 1 (weak_ptr doesn't increase count) if (auto locked = wp.lock()) { // lock() returns shared_ptr if still alive std::cout << *locked; // 50 } sp.reset(); // resource freed std::cout << wp.expired(); // 1 (true — resource gone)
-
-
collapsed:: true
-
Type Ownership Copyable Use Case unique_ptr Exclusive No Single owner, factory returns shared_ptr Shared (ref cnt) Yes Multiple owners, shared data weak_ptr None (observer) Yes Break cycles, cache, observer
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
template <typename T> T maxOf(T a, T b) { return (a > b) ? a : b; } std::cout << maxOf(3, 7); // 7 (int) std::cout << maxOf(3.5, 2.1); // 3.5 (double) std::cout << maxOf('a', 'z'); // z (char) // Multiple type params template <typename T, typename U> auto add(T a, U b) -> decltype(a + b) { return a + b; }
-
-
collapsed:: true
-
template <typename T> class Stack { std::vector<T> data; public: void push(T val) { data.push_back(val); } void pop() { data.pop_back(); } T top() const { return data.back(); } bool empty() const { return data.empty(); } }; Stack<int> si; si.push(1); si.push(2); si.push(3); std::cout << si.top(); // 3 Stack<std::string> ss; ss.push("hello");
-
-
collapsed:: true
-
template <typename T> void print(T val) { std::cout << "Generic: " << val; } // Full specialization for bool template <> void print<bool>(bool val) { std::cout << (val ? "true" : "false"); } print(42); // Generic: 42 print(true); // true
-
-
collapsed:: true
-
// Accept any number of arguments of any types template <typename... Args> void log(Args... args) { (std::cout << ... << args) << "\n"; // fold expression (C++17) } log("Value: ", 42, " and ", 3.14); // Output: Value: 42 and 3.14
-
-
collapsed:: true
-
#include <concepts> // Define a concept template <typename T> concept Numeric = std::integral<T> || std::floating_point<T>; // Use concept to constrain template template <Numeric T> T square(T x) { return x * x; } std::cout << square(5); // 25 std::cout << square(2.5); // 6.25 // square("hi"); // compile error — not Numeric // Shorthand with auto auto multiply(Numeric auto a, Numeric auto b) { return a * b; }
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
Container Type Use Case vector Sequence Dynamic array, fast random access deque Sequence Fast insert/remove at both ends list Sequence Fast insert/remove anywhere array Sequence Fixed-size array stack Adaptor LIFO queue Adaptor FIFO priority_queue Adaptor Max-heap by default set Associative Unique sorted keys multiset Associative Sorted keys, duplicates allowed map Associative Key-value, sorted by key multimap Associative Key-value, duplicate keys allowed unordered_set Unordered Hash set, O(1) avg lookup unordered_map Unordered Hash map, O(1) avg lookup
-
-
collapsed:: true
-
#include <vector> std::vector<int> v = {1, 2, 3}; v.push_back(4); // {1,2,3,4} v.pop_back(); // {1,2,3} v.insert(v.begin()+1, 99); // {1,99,2,3} v.erase(v.begin()+1); // {1,2,3} std::cout << v[0]; // 1 std::cout << v.at(1); // 2 (bounds-checked) std::cout << v.size();// 3 std::cout << v.front(); // 1 std::cout << v.back(); // 3 v.reserve(100); // pre-allocate capacity v.clear(); // remove all elements // iterate for (auto& x : v) std::cout << x << " ";
-
-
collapsed:: true
-
#include <map> #include <unordered_map> std::map<std::string, int> scores; scores["Alice"] = 95; scores["Bob"] = 87; scores.insert({"Charlie", 91}); std::cout << scores["Alice"]; // 95 std::cout << scores.count("Bob"); // 1 (exists) scores.erase("Bob"); for (const auto& [key, val] : scores) { // structured bindings C++17 std::cout << key << ": " << val << "\n"; } // unordered_map — O(1) avg, no ordering std::unordered_map<std::string, int> umap; umap["x"] = 10;
-
-
collapsed:: true
-
#include <set> std::set<int> s = {5, 3, 1, 4, 2}; // automatically sorted: {1,2,3,4,5} s.insert(6); s.erase(3); std::cout << s.count(4); // 1 (exists) for (int x : s) std::cout << x << " "; // 1 2 4 5 6
-
-
collapsed:: true
-
#include <stack> #include <queue> // Stack (LIFO) std::stack<int> st; st.push(1); st.push(2); st.push(3); std::cout << st.top(); // 3 st.pop(); // Queue (FIFO) std::queue<int> q; q.push(1); q.push(2); q.push(3); std::cout << q.front(); // 1 q.pop(); // Priority Queue (max-heap by default) std::priority_queue<int> pq; pq.push(3); pq.push(1); pq.push(5); std::cout << pq.top(); // 5 // Min-heap std::priority_queue<int, std::vector<int>, std::greater<int>> minpq; minpq.push(3); minpq.push(1); minpq.push(5); std::cout << minpq.top(); // 1
-
-
collapsed:: true
-
#include <algorithm> #include <numeric> std::vector<int> v = {5, 3, 1, 4, 2}; std::sort(v.begin(), v.end()); // {1,2,3,4,5} std::sort(v.begin(), v.end(), std::greater<int>()); // {5,4,3,2,1} std::reverse(v.begin(), v.end()); auto it = std::find(v.begin(), v.end(), 3); if (it != v.end()) std::cout << "found at " << (it - v.begin()); int sum = std::accumulate(v.begin(), v.end(), 0); // sum all int mx = *std::max_element(v.begin(), v.end()); int mn = *std::min_element(v.begin(), v.end()); std::count(v.begin(), v.end(), 3); // count occurrences of 3 // transform — apply function to each element std::transform(v.begin(), v.end(), v.begin(), [](int x){ return x * 2; }); // remove_if + erase idiom v.erase(std::remove_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; }), v.end()); // binary search (requires sorted range) std::sort(v.begin(), v.end()); bool found = std::binary_search(v.begin(), v.end(), 3);
-
-
collapsed:: true
-
std::vector<int> v = {10, 20, 30, 40}; auto it = v.begin(); // iterator to first element auto end = v.end(); // iterator past last element std::cout << *it; // 10 ++it; std::cout << *it; // 20 // reverse iterator for (auto rit = v.rbegin(); rit != v.rend(); ++rit) std::cout << *rit << " "; // 40 30 20 10 // const iterator for (auto cit = v.cbegin(); cit != v.cend(); ++cit) std::cout << *cit << " ";
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <stdexcept> double divide(double a, double b) { if (b == 0) throw std::invalid_argument("Division by zero"); return a / b; } try { std::cout << divide(10, 2); // 5 std::cout << divide(10, 0); // throws } catch (const std::invalid_argument& e) { std::cerr << "Error: " << e.what(); } catch (const std::exception& e) { std::cerr << "Exception: " << e.what(); } catch (...) { std::cerr << "Unknown exception"; }
-
-
collapsed:: true
-
std::exception ├── std::logic_error │ ├── std::invalid_argument │ ├── std::out_of_range │ └── std::length_error └── std::runtime_error ├── std::overflow_error ├── std::underflow_error └── std::range_error
-
-
collapsed:: true
-
class AppError : public std::exception { std::string msg; public: AppError(std::string m) : msg(m) {} const char* what() const noexcept override { return msg.c_str(); } }; throw AppError("Something went wrong");
-
-
collapsed:: true
-
void safeFunc() noexcept { // guarantees no exception is thrown // if one is thrown, std::terminate() is called } // noexcept is important for move constructors — enables optimizations Buffer(Buffer&& o) noexcept { ... }
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
// auto type deduction auto x = 42; // Range-based for for (const auto& item : container) { ... } // nullptr int* p = nullptr; // Lambda expressions auto fn = [](int x) { return x * 2; }; // Smart pointers auto sp = std::make_shared<MyClass>(); // Move semantics std::string s = std::move(other); // Initializer lists std::vector<int> v = {1, 2, 3, 4, 5}; // constexpr constexpr int SIZE = 256; // static_assert static_assert(sizeof(int) == 4, "int must be 4 bytes"); // Delegating constructors class Foo { Foo(int x) : Foo(x, 0) {} Foo(int x, int y) { ... } }; // override & final void foo() override final {} // Scoped enums enum class Color { Red, Green, Blue }; Color c = Color::Red;
-
-
collapsed:: true
-
// Generic lambdas auto add = [](auto a, auto b) { return a + b; }; // Return type deduction auto square(int x) { return x * x; } // std::make_unique auto p = std::make_unique<int>(42); // Binary literals & digit separators int flags = 0b1010'1010; long big = 1'000'000;
-
-
collapsed:: true
-
// Structured bindings auto [x, y] = std::pair{1, 2}; for (auto& [key, val] : myMap) { ... } // if constexpr — compile-time branching template <typename T> void process(T val) { if constexpr (std::is_integral_v<T>) { std::cout << "integer: " << val; } else { std::cout << "other: " << val; } } // std::optional — value that may or may not exist #include <optional> std::optional<int> findValue(bool found) { if (found) return 42; return std::nullopt; } auto val = findValue(true); if (val) std::cout << *val; // 42 // std::variant — type-safe union #include <variant> std::variant<int, double, std::string> v = "hello"; std::cout << std::get<std::string>(v); // std::any — holds any type #include <any> std::any a = 42; a = std::string("hello"); std::cout << std::any_cast<std::string>(a); // Filesystem #include <filesystem> namespace fs = std::filesystem; fs::create_directory("mydir"); for (auto& entry : fs::directory_iterator(".")) { std::cout << entry.path() << "\n"; } // Parallel algorithms #include <execution> std::sort(std::execution::par, v.begin(), v.end());
-
-
collapsed:: true
-
// Concepts (see Templates section) template <std::integral T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } // Ranges — composable, lazy algorithms #include <ranges> auto v = std::vector{1,2,3,4,5,6,7,8,9,10}; auto result = v | std::views::filter([](int x){ return x % 2 == 0; }) | std::views::transform([](int x){ return x * x; }); for (int x : result) std::cout << x << " "; // 4 16 36 64 100 // Coroutines (co_await, co_yield, co_return) #include <coroutine> // Used for async code, generators, lazy sequences // std::span — non-owning view over contiguous data #include <span> void process(std::span<int> data) { for (int x : data) std::cout << x; } int arr[] = {1,2,3}; process(arr); // Three-way comparison operator <=> auto result = (5 <=> 3); // std::strong_ordering::greater // Modules (replaces #include for large projects) // import std; // import entire standard library (compiler support varies) // consteval — must be evaluated at compile time consteval int square(int x) { return x * x; } constexpr int s = square(5); // 25
-
-
collapsed:: true
-
// std::print / std::println (finally!) #include <print> std::println("Hello, {}!", "World"); std::print("x = {}, y = {}\n", 1, 2); // std::expected — error handling without exceptions #include <expected> std::expected<int, std::string> divide(int a, int b) { if (b == 0) return std::unexpected("division by zero"); return a / b; } auto r = divide(10, 2); if (r) std::cout << *r; else std::cout << r.error(); // std::flat_map / std::flat_set — cache-friendly sorted containers // Deducing this (explicit object parameter) struct Widget { auto& value(this auto& self) { return self.val; } int val; };
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <thread> #include <iostream> void task(int id) { std::cout << "Thread " << id << " running\n"; } int main() { std::thread t1(task, 1); std::thread t2(task, 2); t1.join(); // wait for t1 to finish t2.join(); // wait for t2 to finish // t.detach() — run independently (fire and forget) }
-
-
collapsed:: true
-
#include <mutex> std::mutex mtx; int counter = 0; void increment() { std::lock_guard<std::mutex> lock(mtx); // RAII lock — auto-unlocks counter++; } // unique_lock — more flexible (can unlock manually) void process() { std::unique_lock<std::mutex> lock(mtx); // do work... lock.unlock(); // do non-critical work... lock.lock(); }
-
-
collapsed:: true
-
#include <condition_variable> std::mutex mtx; std::condition_variable cv; bool ready = false; void worker() { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, []{ return ready; }); // wait until ready == true std::cout << "Worker running\n"; } void producer() { std::lock_guard<std::mutex> lock(mtx); ready = true; cv.notify_one(); // wake one waiting thread }
-
-
collapsed:: true
-
#include <future> int compute(int x) { return x * x; } // Launch async task std::future<int> f = std::async(std::launch::async, compute, 5); // Do other work... int result = f.get(); // blocks until result is ready std::cout << result; // 25 // std::promise — manually set a future value std::promise<int> p; std::future<int> fut = p.get_future(); std::thread t([&p]{ p.set_value(42); }); std::cout << fut.get(); // 42 t.join();
-
-
collapsed:: true
-
#include <atomic> std::atomic<int> counter{0}; void increment() { counter++; // atomic — thread-safe, no mutex needed counter.fetch_add(1); // explicit atomic add } std::cout << counter.load(); // atomic read counter.store(0); // atomic write // Compare-and-swap int expected = 5; counter.compare_exchange_strong(expected, 10); // if counter == 5, set to 10; else load current into expected
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <fstream> #include <string> // Write to file std::ofstream outFile("data.txt"); if (outFile.is_open()) { outFile << "Hello, File!\n"; outFile << "Line 2\n"; outFile.close(); } // Read from file std::ifstream inFile("data.txt"); std::string line; while (std::getline(inFile, line)) { std::cout << line << "\n"; } inFile.close(); // Append to file std::ofstream appendFile("data.txt", std::ios::app); appendFile << "Appended line\n";
-
-
collapsed:: true
-
struct Point { int x, y; }; // Write binary std::ofstream out("points.bin", std::ios::binary); Point p{10, 20}; out.write(reinterpret_cast<char*>(&p), sizeof(p)); // Read binary std::ifstream in("points.bin", std::ios::binary); Point q; in.read(reinterpret_cast<char*>(&q), sizeof(q)); std::cout << q.x << ", " << q.y; // 10, 20
-
-
collapsed:: true
-
#include <sstream> // Build string with stream std::ostringstream oss; oss << "Name: " << "Alice" << ", Age: " << 30; std::string result = oss.str(); // Parse string std::istringstream iss("10 20 30"); int a, b, c; iss >> a >> b >> c; // a=10, b=20, c=30
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
namespace Math { const double PI = 3.14159; int square(int x) { return x * x; } namespace Trig { double sin(double x) { return std::sin(x); } } } std::cout << Math::PI; // 3.14159 std::cout << Math::square(5); // 25 std::cout << Math::Trig::sin(0.5); // nested namespace // using declaration using Math::square; std::cout << square(4); // 16 // using directive (avoid in headers) using namespace Math; std::cout << PI; // 3.14159 // Inline namespace (C++11) — for versioning namespace Lib { inline namespace v2 { void func() { std::cout << "v2"; } } } Lib::func(); // calls v2::func
-
-
collapsed:: true
-
// Limits visibility to current translation unit (like static in C) namespace { int internalHelper() { return 42; } } // internalHelper() only accessible in this .cpp file
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <iostream> // system header #include "myfile.h" // local header #define PI 3.14159 #define MAX(a,b) ((a) > (b) ? (a) : (b)) #undef PI #ifdef DEBUG std::cout << "Debug mode\n"; #elif defined VERBOSE std::cout << "Verbose mode\n"; #else std::cout << "Release mode\n"; #endif #ifndef MYHEADER_H #define MYHEADER_H // header content #endif #pragma once // modern alternative to include guards #error "Unsupported platform" // compile-time error
-
-
collapsed:: true
-
__FILE__ // current filename __LINE__ // current line number __DATE__ // compilation date "MMM DD YYYY" __TIME__ // compilation time "HH:MM:SS" __cplusplus // C++ standard version (201703L = C++17, 202002L = C++20) __func__ // current function name (C++11)
-
-
collapsed:: true
-
// myclass.h — declaration #pragma once class MyClass { public: void hello(); }; // myclass.cpp — definition #include "myclass.h" #include <iostream> void MyClass::hello() { std::cout << "Hello!\n"; } // main.cpp #include "myclass.h" int main() { MyClass obj; obj.hello(); } // Compile: // g++ main.cpp myclass.cpp -o app
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <type_traits> std::is_integral<int>::value // true std::is_floating_point<double>::value // true std::is_pointer<int*>::value // true std::is_same<int, int>::value // true std::is_base_of<Base, Derived>::value // true // Shorthand (C++17) std::is_integral_v<int> // true std::is_same_v<int, float> // false // Conditional type std::conditional_t<true, int, double> // int std::conditional_t<false, int, double> // double // Remove/add qualifiers std::remove_const_t<const int> // int std::add_pointer_t<int> // int*
-
-
collapsed:: true
-
// Substitution Failure Is Not An Error // Enable function only for integral types template <typename T> typename std::enable_if_t<std::is_integral_v<T>, T> double_it(T x) { return x * 2; } double_it(5); // works // double_it(3.14); // compile error — not integral // C++20 Concepts are cleaner — prefer those
-
-
collapsed:: true
-
constexpr int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); } constexpr int f5 = factorial(5); // computed at compile time: 120 // constexpr if (C++17) template <typename T> auto process(T val) { if constexpr (std::is_integral_v<T>) return val * 2; else return val + 0.5; } // consteval (C++20) — MUST be compile-time consteval int square(int x) { return x * x; }
-
-
collapsed:: true
-
// alignas — specify alignment alignas(16) float simdData[4]; // 16-byte aligned for SIMD // alignof — query alignment std::cout << alignof(double); // typically 8 // std::aligned_storage (C++11) std::aligned_storage_t<sizeof(int), alignof(int)> storage; // Placement new — construct in pre-allocated memory char buf[sizeof(MyClass)]; MyClass* obj = new (buf) MyClass(); // construct in buf obj->~MyClass(); // must manually call destructor
-
-
collapsed:: true
-
// Singleton class Singleton { static Singleton* instance; Singleton() {} public: static Singleton& getInstance() { static Singleton inst; // thread-safe in C++11 return inst; } }; // Factory class Shape { public: virtual void draw() = 0; }; class Circle : public Shape { public: void draw() override { std::cout << "Circle\n"; } }; class Square : public Shape { public: void draw() override { std::cout << "Square\n"; } }; std::unique_ptr<Shape> createShape(std::string type) { if (type == "circle") return std::make_unique<Circle>(); if (type == "square") return std::make_unique<Square>(); return nullptr; } // Observer class Observer { public: virtual void update(int val) = 0; }; class Subject { std::vector<Observer*> observers; int state; public: void attach(Observer* o) { observers.push_back(o); } void setState(int s) { state = s; for (auto* o : observers) o->update(state); } };
-
-
collapsed:: true
-
// Unpack pairs, tuples, structs, arrays auto [x, y] = std::make_pair(1, 2); std::tuple<int, std::string, double> t{1, "hello", 3.14}; auto [id, name, score] = t; struct Point { int x, y; }; Point p{10, 20}; auto [px, py] = p; // In range-based for std::map<std::string, int> m{{"a", 1}, {"b", 2}}; for (auto& [key, val] : m) { std::cout << key << "=" << val << "\n"; }
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <utility> #include <tuple> // pair — two values std::pair<std::string, int> p = {"Alice", 30}; std::cout << p.first << ", " << p.second; // Alice, 30 auto p2 = std::make_pair("Bob", 25); // tuple — N values of different types std::tuple<int, std::string, double> t = {1, "hello", 3.14}; std::cout << std::get<0>(t); // 1 std::cout << std::get<1>(t); // hello std::cout << std::get<2>(t); // 3.14 auto t2 = std::make_tuple(42, "world", 2.71); // structured binding (C++17) auto [id, name, score] = t; // tie — unpack into existing variables int a; std::string b; std::tie(a, b, std::ignore) = t;
-
-
collapsed:: true
-
#include <deque> #include <list> #include <forward_list> // deque — double-ended queue, fast insert/remove at both ends std::deque<int> dq = {2, 3, 4}; dq.push_front(1); // {1,2,3,4} dq.push_back(5); // {1,2,3,4,5} dq.pop_front(); // {2,3,4,5} std::cout << dq[1]; // 3 // list — doubly linked list, O(1) insert/remove anywhere std::list<int> lst = {1, 2, 3, 4}; auto it = lst.begin(); std::advance(it, 2); lst.insert(it, 99); // {1,2,99,3,4} lst.remove(2); // removes all 2s lst.sort(); lst.reverse(); // forward_list — singly linked, minimal memory std::forward_list<int> fl = {3, 1, 4, 1, 5}; fl.push_front(0); fl.sort(); fl.unique(); // remove consecutive duplicates
-
-
collapsed:: true
-
#include <initializer_list> // Accept brace-init in your own functions/classes void printAll(std::initializer_list<int> vals) { for (int v : vals) std::cout << v << " "; } printAll({1, 2, 3, 4, 5}); // 1 2 3 4 5 class NumberSet { std::vector<int> data; public: NumberSet(std::initializer_list<int> list) : data(list) {} void print() { for (int x : data) std::cout << x << " "; } }; NumberSet ns{10, 20, 30}; // uses initializer_list constructor ns.print(); // 10 20 30
-
-
collapsed:: true
-
#include <chrono> #include <thread> using namespace std::chrono; // Get current time auto start = high_resolution_clock::now(); // Simulate work std::this_thread::sleep_for(milliseconds(100)); auto end = high_resolution_clock::now(); auto elapsed = duration_cast<milliseconds>(end - start); std::cout << "Elapsed: " << elapsed.count() << "ms\n"; // Duration literals (C++14) auto t1 = 2s; // 2 seconds auto t2 = 500ms; // 500 milliseconds auto t3 = 1min; // 1 minute // Time point arithmetic auto now = system_clock::now(); auto future = now + hours(24); // 24 hours from now // Convert to time_t for display auto tt = system_clock::to_time_t(now); std::cout << std::ctime(&tt);
-
-
collapsed:: true
-
#include <random> // Mersenne Twister engine (high quality) std::mt19937 rng(std::random_device{}()); // seed with hardware entropy // Uniform integer distribution std::uniform_int_distribution<int> dice(1, 6); std::cout << dice(rng); // random 1-6 // Uniform real distribution std::uniform_real_distribution<double> prob(0.0, 1.0); std::cout << prob(rng); // random 0.0-1.0 // Normal distribution std::normal_distribution<double> normal(0.0, 1.0); // mean=0, stddev=1 std::cout << normal(rng); // Shuffle a container std::vector<int> v = {1, 2, 3, 4, 5}; std::shuffle(v.begin(), v.end(), rng);
-
-
collapsed:: true
-
#include <regex> #include <string> std::string text = "Hello, my email is user@example.com"; std::regex emailPattern(R"(\w+@\w+\.\w+)"); // Check if match exists if (std::regex_search(text, emailPattern)) { std::cout << "Email found!\n"; } // Extract match std::smatch match; if (std::regex_search(text, match, emailPattern)) { std::cout << "Found: " << match[0]; // user@example.com } // Full match std::regex intPattern(R"(\d+)"); std::cout << std::regex_match("12345", intPattern); // 1 (true) // Replace std::string result = std::regex_replace(text, emailPattern, "[REDACTED]"); std::cout << result; // Iterate all matches std::sregex_iterator it(text.begin(), text.end(), emailPattern); std::sregex_iterator end; for (; it != end; ++it) std::cout << (*it)[0] << "\n";
-
-
collapsed:: true
-
#include <format> // Basic formatting std::string s = std::format("Hello, {}!", "World"); std::cout << s; // Hello, World! // Multiple args std::cout << std::format("Name: {}, Age: {}", "Alice", 30); // Positional args std::cout << std::format("{0} + {1} = {2}", 3, 4, 7); // Format specifiers std::cout << std::format("{:.2f}", 3.14159); // 3.14 std::cout << std::format("{:>10}", "right"); // right-aligned std::cout << std::format("{:0>5}", 42); // 00042 std::cout << std::format("{:#x}", 255); // 0xff std::cout << std::format("{:b}", 10); // 1010 (binary) // C++23: std::print (directly to stdout) // std::println("Value: {}", 42);
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
int global = 10; // global scope — accessible everywhere in file void foo() { int local = 5; // local scope — only inside foo() { int block = 3; // block scope — only inside this {} std::cout << local + block; // 8 } // block is destroyed here } // Shadowing — inner variable hides outer int x = 1; { int x = 2; // shadows outer x std::cout << x; // 2 } std::cout << x; // 1
-
-
collapsed:: true
-
// Automatic — default for local variables, destroyed at end of scope void foo() { int x = 5; } // x destroyed when foo() returns // Static — persists for program lifetime void counter() { static int count = 0; // initialized once, persists between calls count++; std::cout << count; } counter(); // 1 counter(); // 2 counter(); // 3 // Dynamic — heap, controlled by new/delete or smart pointers int* p = new int(42); delete p; // Thread-local (C++11) — one copy per thread thread_local int tls = 0;
-
-
collapsed:: true
-
// External linkage — visible across translation units int globalVar = 42; // external by default extern int globalVar; // declare in other .cpp files // Internal linkage — visible only in current translation unit static int fileLocal = 10; // static at file scope = internal linkage namespace { int anon = 5; } // anonymous namespace = internal linkage // inline variables (C++17) — define in header, one definition across TUs inline int sharedConst = 100; // constinit (C++20) — guarantee static init at compile time constinit int initAtCompileTime = 42;
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
int a = 0b1010; // 10 int b = 0b1100; // 12 std::cout << (a & b); // AND → 0b1000 = 8 std::cout << (a | b); // OR → 0b1110 = 14 std::cout << (a ^ b); // XOR → 0b0110 = 6 std::cout << (~a); // NOT → -11 (two's complement) std::cout << (a << 1); // LEFT SHIFT → 0b10100 = 20 std::cout << (a >> 1); // RIGHT SHIFT → 0b0101 = 5
-
-
collapsed:: true
-
int n = 42; // Check if bit i is set bool isSet = (n >> i) & 1; // Set bit i n |= (1 << i); // Clear bit i n &= ~(1 << i); // Toggle bit i n ^= (1 << i); // Check if power of 2 bool isPow2 = n > 0 && (n & (n - 1)) == 0; // Count set bits (popcount) int bits = __builtin_popcount(n); // GCC/Clang int bits2 = std::popcount((unsigned)n); // C++20 <bit> // Isolate lowest set bit int lowest = n & (-n); // Clear lowest set bit n = n & (n - 1); // Swap without temp a ^= b; b ^= a; a ^= b;
-
-
collapsed:: true
-
#include <bitset> std::bitset<8> bits(0b10110100); // 8-bit set std::cout << bits; // 10110100 std::cout << bits[3]; // 0 (bit at position 3) std::cout << bits.count(); // 4 (number of set bits) std::cout << bits.size(); // 8 bits.set(0); // set bit 0 → 10110101 bits.reset(7); // clear bit 7 → 00110101 bits.flip(1); // toggle bit 1 bits.flip(); // flip all bits std::cout << bits.to_ulong(); // convert to unsigned long std::cout << bits.to_string(); // convert to string // Bitwise ops on bitsets std::bitset<8> a(0b1010), b(0b1100); std::cout << (a & b); // 00001000 std::cout << (a | b); // 00001110 std::cout << (a ^ b); // 00000110
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
# Basic compile g++ main.cpp -o app # Specify C++ standard g++ -std=c++17 main.cpp -o app g++ -std=c++20 main.cpp -o app # Multiple files g++ -std=c++17 main.cpp utils.cpp -o app # Optimization levels g++ -O0 main.cpp -o app # no optimization (debug) g++ -O2 main.cpp -o app # standard optimization g++ -O3 main.cpp -o app # aggressive optimization # Debug info (for gdb/lldb) g++ -g -std=c++17 main.cpp -o app # Warnings g++ -Wall -Wextra -std=c++17 main.cpp -o app # Define macros g++ -DDEBUG main.cpp -o app # Include path & link library g++ -I./include -L./lib -lmylib main.cpp -o app
-
-
collapsed:: true
-
# CMakeLists.txt cmake_minimum_required(VERSION 3.20) project(MyApp VERSION 1.0) set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED True) # Add executable add_executable(MyApp main.cpp utils.cpp) # Add library add_library(MyLib STATIC lib.cpp) target_link_libraries(MyApp PRIVATE MyLib) # Include directories target_include_directories(MyApp PRIVATE include/) # Build: # mkdir build && cd build # cmake .. # cmake --build .
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
// Old-style enum (pollutes namespace) enum Direction { North, South, East, West }; Direction d = North; // Scoped enum (C++11) — preferred enum class Color { Red, Green, Blue }; Color c = Color::Red; // Enum with underlying type enum class Status : uint8_t { OK = 0, Error = 1, Pending = 2 }; // Cast to underlying type int val = static_cast<int>(Color::Green); // 1
-
-
collapsed:: true
-
// C-style union — unsafe, no type tracking union Data { int i; float f; char c; }; Data d; d.i = 42; // std::variant (C++17) — type-safe union std::variant<int, float, std::string> v = 42; v = 3.14f; v = "hello"; std::visit([](auto&& val) { std::cout << val; }, v);
-
-
collapsed:: true
-
\n Newline \t Horizontal tab \r Carriage return \\ Backslash \' Single quote \" Double quote \0 Null character \a Bell/alert \b Backspace \f Form feed \v Vertical tab \xNN Hex value (e.g. \x41 = 'A') \uNNNN Unicode (C++11)
-
-
collapsed:: true
-
<iostream> // cin, cout, cerr <string> // std::string <vector> // std::vector <array> // std::array <map> // std::map <set> // std::set <unordered_map> // std::unordered_map <algorithm> // sort, find, transform... <numeric> // accumulate, iota... <functional> // std::function, std::bind <memory> // smart pointers <thread> // std::thread <mutex> // std::mutex <future> // std::async, std::future <atomic> // std::atomic <fstream> // file I/O <sstream> // string streams <filesystem> // fs operations (C++17) <optional> // std::optional (C++17) <variant> // std::variant (C++17) <any> // std::any (C++17) <span> // std::span (C++20) <ranges> // ranges & views (C++20) <concepts> // concepts (C++20) <format> // std::format (C++20) <print> // std::print (C++23) <expected> // std::expected (C++23) <cmath> // math functions <cstring> // C string functions <cassert> // assert() <stdexcept> // standard exceptions <type_traits> // type traits <chrono> // time utilities <random> // random number generation <regex> // regular expressions
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
// Integer literals int dec = 255; // decimal int hex = 0xFF; // hexadecimal int oct = 0377; // octal int bin = 0b11111111; // binary (C++14) // Digit separators (C++14) int million = 1'000'000; double pi = 3.141'592'653; // Type suffixes auto a = 42; // int auto b = 42u; // unsigned int auto c = 42l; // long auto d = 42ll; // long long auto e = 42ul; // unsigned long auto f = 3.14f; // float auto g = 3.14; // double auto h = 3.14l; // long double // String literals const char* s1 = "hello"; const wchar_t* s2 = L"wide"; const char16_t* s3 = u"utf16"; const char32_t* s4 = U"utf32"; const char* s5 = u8"utf8"; // Raw string literals (no escape processing) const char* path = R"(C:\Users\name\file.txt)"; const char* regex = R"(\d+\.\d+)"; // User-defined literals (C++11) // operator"" suffix long double operator"" _km(long double d) { return d * 1000.0; } long double dist = 5.0_km; // 5000.0
-
-
collapsed:: true
-
// Old C-style typedef typedef unsigned long long uint64; typedef std::vector<int> IntVec; // Modern using alias (C++11) — preferred using uint64 = unsigned long long; using IntVec = std::vector<int>; using StringMap = std::map<std::string, std::string>; // Alias templates — typedef can't do this template <typename T> using Vec = std::vector<T>; Vec<int> vi = {1, 2, 3}; Vec<std::string> vs = {"a", "b"}; // Function pointer alias using Callback = void(*)(int, int); using Handler = std::function<void(std::string)>;
-
-
collapsed:: true
-
#include <cctype> #include <string> #include <algorithm> char c = 'A'; // Classification std::isalpha(c); // true — is letter std::isdigit(c); // false — is digit std::isalnum(c); // true — is letter or digit std::isspace(c); // false — is whitespace std::isupper(c); // true — is uppercase std::islower(c); // false — is lowercase std::ispunct(c); // false — is punctuation // Conversion std::tolower('A'); // 'a' std::toupper('a'); // 'A' // Convert entire string std::string s = "Hello World"; std::transform(s.begin(), s.end(), s.begin(), ::tolower); // s = "hello world" std::transform(s.begin(), s.end(), s.begin(), ::toupper); // s = "HELLO WORLD" // Count digits in string int digits = std::count_if(s.begin(), s.end(), ::isdigit);
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
// int main(int argc, char* argv[]) // argc — argument count (includes program name) // argv — array of C-strings int main(int argc, char* argv[]) { std::cout << "Program: " << argv[0] << "\n"; std::cout << "Args: " << argc - 1 << "\n"; for (int i = 1; i < argc; i++) { std::cout << "arg[" << i << "] = " << argv[i] << "\n"; } return 0; } // Run: ./app hello world 42 // Program: ./app // Args: 3 // arg[1] = hello // arg[2] = world // arg[3] = 42 // Convert args int n = std::stoi(argv[1]); double d = std::stod(argv[2]);
-
-
collapsed:: true
-
// 1. Return struct struct MinMax { int min, max; }; MinMax getMinMax(std::vector<int>& v) { return { *std::min_element(v.begin(), v.end()), *std::max_element(v.begin(), v.end()) }; } auto [mn, mx] = getMinMax(v); // structured binding // 2. Return std::pair std::pair<bool, int> findFirst(std::vector<int>& v, int target) { for (int i = 0; i < v.size(); i++) if (v[i] == target) return {true, i}; return {false, -1}; } auto [found, idx] = findFirst(v, 3); // 3. Return std::tuple std::tuple<int, int, int> divide(int a, int b) { return {a / b, a % b, b}; } auto [quot, rem, divisor] = divide(17, 5); // 4. Return std::optional (value or nothing) std::optional<int> safeSqrt(int n) { if (n < 0) return std::nullopt; return static_cast<int>(std::sqrt(n)); } if (auto r = safeSqrt(16)) std::cout << *r; // 4 // 5. Output parameters (old style, avoid when possible) void getCoords(int& x, int& y) { x = 10; y = 20; } int x, y; getCoords(x, y);
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <climits> #include <limits> // Numeric limits std::cout << INT_MAX; // 2147483647 std::cout << INT_MIN; // -2147483648 std::cout << UINT_MAX; // 4294967295 std::cout << LLONG_MAX; // 9223372036854775807 // std::numeric_limits (preferred, works for any type) std::cout << std::numeric_limits<int>::max(); std::cout << std::numeric_limits<int>::min(); std::cout << std::numeric_limits<double>::max(); std::cout << std::numeric_limits<double>::epsilon(); // smallest diff std::cout << std::numeric_limits<float>::infinity(); // Overflow wraps around for unsigned (defined behavior) unsigned int u = UINT_MAX; u++; // u = 0 (wraps) // Overflow for signed int is UNDEFINED BEHAVIOR int i = INT_MAX; i++; // UB — don't do this // Safe check before overflow if (a > std::numeric_limits<int>::max() - b) { // would overflow }
-
-
collapsed:: true
-
// Floating point is not exact double a = 0.1 + 0.2; std::cout << (a == 0.3); // 0 (false!) — precision issue // Correct comparison double epsilon = 1e-9; std::cout << (std::abs(a - 0.3) < epsilon); // 1 (true) // Special values double inf = std::numeric_limits<double>::infinity(); double nan = std::numeric_limits<double>::quiet_NaN(); std::cout << std::isinf(inf); // 1 std::cout << std::isnan(nan); // 1 std::cout << std::isfinite(42.0); // 1
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
class Point { public: int x, y; Point(int x, int y) : x(x), y(y) {} void print() { // 'this' is a pointer to the current object std::cout << this->x << ", " << this->y; std::cout << " (at " << this << ")\n"; } // Return *this for method chaining Point& setX(int x) { this->x = x; return *this; } Point& setY(int y) { this->y = y; return *this; } }; Point p(1, 2); p.setX(10).setY(20); // method chaining // sizeof class std::cout << sizeof(Point); // 8 (two ints, no padding needed) // Memory layout: members stored in declaration order // Padding added for alignment struct Padded { char a; int b; char c; }; std::cout << sizeof(Padded); // likely 12, not 6 (padding) struct Packed { int b; char a; char c; }; std::cout << sizeof(Packed); // likely 8 (better layout)
-
-
collapsed:: true
-
class Widget { int id; std::string name; double value; public: // Member initializer list — always prefer over assignment in body // Initialized in DECLARATION ORDER, not list order Widget(int i, std::string n, double v) : id(i), name(std::move(n)), value(v) {} // Delegating constructor (C++11) — one constructor calls another Widget() : Widget(0, "default", 0.0) {} Widget(int i) : Widget(i, "unnamed", 0.0) {} // Converting constructor — implicit conversion from int Widget(int i) : id(i), name(""), value(0) {} // explicit — prevents implicit conversion explicit Widget(double v) : id(0), name(""), value(v) {} }; Widget w1(1, "hello", 3.14); Widget w2; // calls delegating constructor Widget w3 = 42; // implicit conversion (if not explicit) // Widget w4 = 3.14; // ERROR if constructor is explicit Widget w4(3.14); // OK — explicit call // = delete — disable a constructor class NonCopyable { public: NonCopyable() = default; NonCopyable(const NonCopyable&) = delete; // no copy NonCopyable& operator=(const NonCopyable&) = delete; }; // = default — compiler generates default implementation class Simple { public: Simple() = default; ~Simple() = default; };
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <compare> // Returns ordering type, not bool auto r1 = (5 <=> 3); // std::strong_ordering::greater auto r2 = (3 <=> 5); // std::strong_ordering::less auto r3 = (5 <=> 5); // std::strong_ordering::equal // Ordering types: // strong_ordering — for integers (equal means identical) // weak_ordering — for floats (equivalent but not identical) // partial_ordering — for floats with NaN (incomparable possible) // Check result if (r1 > 0) std::cout << "greater"; if (r1 < 0) std::cout << "less"; if (r1 == 0) std::cout << "equal"; // Auto-generate all comparison operators from <=> struct Point { int x, y; auto operator<=>(const Point&) const = default; // Now ==, !=, <, >, <=, >= all work automatically }; Point a{1, 2}, b{1, 3}; std::cout << (a < b); // true std::cout << (a == b); // false // Custom spaceship operator struct Version { int major, minor, patch; std::strong_ordering operator<=>(const Version& o) const { if (auto c = major <=> o.major; c != 0) return c; if (auto c = minor <=> o.minor; c != 0) return c; return patch <=> o.patch; } bool operator==(const Version&) const = default; };
-
-
collapsed:: true
-
// && stops at first false // || stops at first true int x = 0; if (x != 0 && 10 / x > 1) { // safe — 10/x never evaluated if x==0 std::cout << "ok"; } // Useful for null checks std::string* p = nullptr; if (p != nullptr && p->length() > 0) { // safe std::cout << *p; } // Side effects in conditions (avoid, but know it exists) int a = 0, b = 0; if (++a || ++b) { // b is never incremented std::cout << a << " " << b; // 1 0 }
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
// A class with operator() — behaves like a function but has state class Multiplier { int factor; public: Multiplier(int f) : factor(f) {} int operator()(int x) const { return x * factor; } }; Multiplier triple(3); std::cout << triple(5); // 15 std::cout << triple(10); // 30 // Used with STL algorithms std::vector<int> v = {1, 2, 3, 4, 5}; std::transform(v.begin(), v.end(), v.begin(), Multiplier(2)); // v = {2, 4, 6, 8, 10}
-
-
collapsed:: true
-
#include <functional> int add(int a, int b) { return a + b; } // Bind first argument to 10 auto add10 = std::bind(add, 10, std::placeholders::_1); std::cout << add10(5); // 15 std::cout << add10(20); // 30 // Bind member function class Printer { public: void print(std::string msg) { std::cout << msg; } }; Printer p; auto fn = std::bind(&Printer::print, &p, std::placeholders::_1); fn("Hello"); // Hello // Note: prefer lambdas over std::bind in modern C++ auto add10_lambda = [](int x) { return add(10, x); };
-
-
collapsed:: true
-
#include <functional> // Uniformly call any callable: function, lambda, functor, member fn int add(int a, int b) { return a + b; } std::invoke(add, 3, 4); // 7 — free function std::invoke([](int x){ return x*2; }, 5); // 10 — lambda struct Foo { int val; int get() { return val; } }; Foo f{42}; std::invoke(&Foo::get, f); // 42 — member function std::invoke(&Foo::val, f); // 42 — member variable
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
#include <ranges> #include <vector> std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // filter — keep only even numbers auto evens = v | std::views::filter([](int x){ return x % 2 == 0; }); // transform — square each auto squared = evens | std::views::transform([](int x){ return x * x; }); // Chain (lazy — nothing computed until iterated) for (int x : squared) std::cout << x << " "; // 4 16 36 64 100 // take / drop auto first3 = v | std::views::take(3); // {1, 2, 3} auto skip2 = v | std::views::drop(2); // {3, 4, 5, ...} // reverse auto rev = v | std::views::reverse; // iota — generate sequence for (int i : std::views::iota(1, 6)) std::cout << i; // 12345 // keys / values (for maps) std::map<std::string, int> m{{"a",1},{"b",2}}; for (auto& k : m | std::views::keys) std::cout << k; // ab for (auto& v : m | std::views::values) std::cout << v; // 12
-
-
collapsed:: true
-
#include <algorithm> #include <ranges> std::vector<int> v = {5, 3, 1, 4, 2}; // Ranges versions — no begin/end needed std::ranges::sort(v); // {1,2,3,4,5} std::ranges::reverse(v); // {5,4,3,2,1} auto it = std::ranges::find(v, 3); bool found = std::ranges::contains(v, 3); // C++23 std::ranges::sort(v, std::greater{}); // descending std::ranges::sort(v, {}, &MyStruct::key); // sort by member // Projections — transform before comparing struct Person { std::string name; int age; }; std::vector<Person> people = {{"Bob",30},{"Alice",25}}; std::ranges::sort(people, {}, &Person::age); // sort by age std::ranges::sort(people, {}, &Person::name); // sort by name
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
- A coroutine is a function that can suspend and resume execution.
- Uses three keywords:
co_await,co_yield,co_return - Requires a promise type and a coroutine handle — usually provided by a library.
-
#include <coroutine> #include <iostream> // Minimal generator coroutine struct Generator { struct promise_type { int current_value; Generator get_return_object() { return Generator{std::coroutine_handle<promise_type>::from_promise(*this)}; } std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { return {}; } std::suspend_always yield_value(int v) { current_value = v; return {}; } void return_void() {} void unhandled_exception() { std::terminate(); } }; std::coroutine_handle<promise_type> handle; Generator(std::coroutine_handle<promise_type> h) : handle(h) {} ~Generator() { if (handle) handle.destroy(); } bool next() { handle.resume(); return !handle.done(); } int value() { return handle.promise().current_value; } }; Generator counter(int start, int end) { for (int i = start; i <= end; i++) co_yield i; // suspend and yield value } auto gen = counter(1, 5); while (gen.next()) std::cout << gen.value() << " "; // 1 2 3 4 5
-
collapsed:: true
-
// co_await suspends the coroutine until the awaitable completes // Used for async I/O, networking, task scheduling // Conceptual async task (real impl needs a scheduler/runtime) Task<int> fetchData() { auto result = co_await asyncHttpGet("https://api.example.com"); co_return result.statusCode; } // std::suspend_always — always suspends // std::suspend_never — never suspends (runs to completion) // In practice, use a library: // - cppcoro (popular coroutine library) // - Asio (networking with coroutines) // - C++23 std::generator for simple generators
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
- Modules replace
#include— faster compilation, no header guards, no macro leakage. -
// math.ixx (or math.cppm) — module interface unit export module math; // declare module export int add(int a, int b) { return a + b; } // exported — visible to importers int helper() { return 42; } // NOT exported — internal only export namespace Math { double pi = 3.14159; double square(double x) { return x * x; } }
-
// main.cpp — import the module import math; int main() { std::cout << add(3, 4); // 7 std::cout << Math::square(5); // 25 // helper() — ERROR, not exported }
- Modules replace
-
collapsed:: true
-
// Partition — split large module into parts export module mylib:utils; // partition "utils" of module "mylib" export void utilFunc() {} // Primary module imports its partitions export module mylib; export import :utils; // Import standard library (C++23, compiler support varies) import std; // import everything import std.core; // core subset // Compile with modules (g++/clang++) // g++ -std=c++20 -fmodules-ts math.ixx main.cpp -o app
-
-
collapsed:: true
-
collapsed:: true
-
collapsed:: true
-
Iterator Category Operations Example Input ++, *, ==, != istream_iterator Output ++, *= ostream_iterator Forward ++, *, ==, != forward_list::iterator Bidirectional ++, --, *, ==, != list::iterator Random Access ++, --, +, -, [], < vector::iterator Contiguous (C++20) Random Access + contiguous memory vector::iterator
-
-
collapsed:: true
-
#include <iterator> template <typename T> class Range { T start_, end_, step_; public: Range(T start, T end, T step = 1) : start_(start), end_(end), step_(step) {} struct Iterator { using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = std::ptrdiff_t; using pointer = T*; using reference = T&; T current, step; Iterator(T c, T s) : current(c), step(s) {} T operator*() const { return current; } Iterator& operator++() { current += step; return *this; } Iterator operator++(int) { auto tmp = *this; ++(*this); return tmp; } bool operator==(const Iterator& o) const { return current >= o.current; } bool operator!=(const Iterator& o) const { return !(*this == o); } }; Iterator begin() { return Iterator(start_, step_); } Iterator end() { return Iterator(end_, step_); } }; // Usage — works with range-based for and STL algorithms for (int i : Range(1, 10, 2)) std::cout << i << " "; // 1 3 5 7 9 Range<double> r(0.0, 1.0, 0.25); std::vector<double> v(r.begin(), r.end()); // {0.0, 0.25, 0.5, 0.75}
-
-
collapsed:: true
-
id:: 673ac308-24d0-40b6-b0d7-a4b6cac5b79a
- [[Cpp for Unreal]] - Unreal-specific C++ patterns: UObject system, UPROPERTY/UFUNCTION macros, TArray/TMap, delegates, GC, networking replication.
- [[Standard Template Library]] - Vectors, maps, sets, algorithms, iterators — the backbone of every C++ program.
- [[Boost]] - Peer-reviewed libraries extending C++: threading, filesystem, smart pointers, regex, and more.
- [[Qt]] - Cross-platform GUI framework with networking, database, and mobile support.
- [[OpenCV]] - Computer vision library for real-time image processing and object detection.
- [[Simple and Fast Multimedia Library]] - Graphics, sound, and input for game development.
- [[Eigen]] - Template library for linear algebra, matrices, and vectors — used in ML and scientific computing.
- [[Cpp REST SDK]] - Cross-platform RESTful web services and HTTP communication.
- [[POCO Cpp Portable Components]] - HTTP, database, JSON/XML parsing for networked applications.
- [[Google Test]] - Unit testing framework with mock objects and assertions.
- [[ACE Adaptive Communicative Environment]] - High-performance networked and real-time systems.
- [[Threading Building Blocks]] - Intel's parallel programming library for multi-core performance.
- [[Simple DirectMedia Layer]] - Cross-platform multimedia: audio, graphics, input for games.
- [[Catch2]] - Modern, header-only C++ testing framework — simpler than gtest.
- [[nlohmann json]] - Single-header JSON library, the most popular C++ JSON parser.
- [[Spdlog]] - Fast, header-only logging library for C++.
-