C++ Syntax Drill
Modern C++ keywords, STL containers, and essential patterns — smart pointers, templates, lambdas, and range-based loops — in one compact reference.
C++ Keywords
| Keyword | Description |
|---|---|
auto | Deduce type from initializer (C++11) |
const | Immutable variable or member (cannot be changed) |
constexpr | Evaluate expression at compile time (C++11) |
consteval | Must be evaluated at compile time (C++20) |
nullptr | Null pointer constant (replaces NULL) |
class | Define a class (default private) |
struct | Define a struct (default public) |
template | Generic type or function parameter |
typename | Introduce a type parameter in templates |
namespace | Group names to avoid collisions |
using | Bring name into scope / type alias |
virtual | Enable polymorphic dispatch (override in subclass) |
override | Explicitly mark a virtual method override (C++11) |
final | Prevent further inheritance or overriding (C++11) |
explicit | Prevent implicit conversions for constructors |
public | Member accessible everywhere |
private | Member accessible only within the class |
protected | Accessible in class and derived classes |
static | Shared across all instances; or local persistent storage |
inline | Hint to expand function at call site |
noexcept | Declare a function won't throw (C++11) |
delete | Disable a function / free heap memory |
new | Allocate on the heap |
operator | Define or override an operator |
mutable | Allow modification in const context |
friend | Grant external access to private members |
typedef | Create a type alias (older style) |
enum class | Strongly typed enumeration (C++11) |
static_assert | Compile-time assertion |
decltype | Query the type of an expression |
STL Containers
Choosing the right container is one of the most important performance decisions in C++.
| Container | Description |
|---|---|
std::vector<T> | Dynamic array — O(1) amortised push_back, random access |
std::array<T, N> | Fixed-size stack array with STL interface |
std::list<T> | Doubly linked list — O(1) insert/erase at position |
std::deque<T> | Double-ended queue — fast front and back push |
std::map<K, V> | Sorted key-value store (red-black tree) — O(log n) |
std::unordered_map<K, V> | Hash map — O(1) average lookup |
std::set<T> | Sorted unique elements — O(log n) |
std::unordered_set<T> | Hash set — O(1) average lookup |
std::multimap<K, V> | Sorted map allowing duplicate keys |
std::priority_queue<T> | Max-heap by default — O(log n) push/pop |
std::queue<T> | FIFO adapter over deque |
std::stack<T> | LIFO adapter over deque |
std::pair<A, B> | Simple two-element tuple |
std::tuple<Ts...> | Heterogeneous fixed-size collection |
std::optional<T> | Value that may or may not be present (C++17) |
std::variant<Ts...> | Type-safe union (C++17) |
std::string | Dynamic character sequence |
std::string_view | Non-owning view of a string (C++17) |
Common Patterns
Hello World & Basics
#include <iostream>
#include <string>
int main() {
std::string name = "World";
std::cout << "Hello, " << name << "!\n";
return 0;
}Range-Based For & Lambda
#include <vector>
#include <algorithm>
#include <iostream>
int main() {
std::vector<int> numbers = {5, 3, 8, 1, 9, 2};
// Range-based for loop
for (const auto& n : numbers) {
std::cout << n << " ";
}
// Sort with lambda
std::sort(numbers.begin(), numbers.end(),
[](int a, int b) { return a < b; });
// Lambda with capture
int threshold = 5;
auto isAbove = [threshold](int n) { return n > threshold; };
auto count = std::count_if(numbers.begin(), numbers.end(), isAbove);
std::cout << "\nAbove threshold: " << count << "\n";
}Smart Pointers
#include <memory>
#include <iostream>
struct Node {
int value;
std::unique_ptr<Node> next;
explicit Node(int val) : value(val) {}
};
int main() {
// unique_ptr — sole ownership, auto-deleted
auto head = std::make_unique<Node>(1);
head->next = std::make_unique<Node>(2);
// shared_ptr — reference counted ownership
auto shared = std::make_shared<Node>(42);
auto also = shared; // ref count = 2
// weak_ptr — non-owning observer
std::weak_ptr<Node> observer = shared;
if (auto locked = observer.lock()) {
std::cout << locked->value << "\n";
}
}Template Function
#include <iostream>
#include <vector>
template<typename T>
T findMax(const std::vector<T>& items) {
if (items.empty()) throw std::runtime_error("Empty container");
T maxVal = items[0];
for (const auto& item : items) {
if (item > maxVal) maxVal = item;
}
return maxVal;
}
int main() {
std::vector<int> ints = {3, 7, 2, 9, 1};
std::cout << findMax(ints) << "\n"; // 9
std::vector<double> dbls = {1.5, 2.7, 0.3};
std::cout << findMax(dbls) << "\n"; // 2.7
}Practice typing these in CodeSpeedTest →
C++ has some of the most symbol-heavy syntax of any language. Getting fluent with angle brackets, scope resolution, and pointer syntax requires deliberate practice.