std::array() has friendlier semantics (discussion).
Conversions
int to string
Enum
Strong enumeration, scoped enumeration
Unscoped enumeration (without class modifier):
Assigning
(scoped enum)
Getting value
(scoped enum)
Optional
Create:
Access:
Check:
Pair
Create:
Destructuring assigment:
NOTE: Works with tuples too.
Ignoring one of the members in the pair:
Strings
Literal
The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time.
View
Optimization for read-only strings which does not make copies on assignment.
string_view::substr() does not copy either.
Sstream
Osstream
Construct streams using the << syntax.
Struct
Initialization:
Type Alias
Collections
Hash Map
In C++ unordered_map implements a hash map. Search, insertion, and removal of elements have average constant-time complexity. Keys don’t have any particular order. map keeps the keys sorted.
Import
Initialization
Empty map:
Access
Emplace
Can be used to avoid the creation of temporary objects.
Warning: only adds to map if the corresponding key does not exist.
Insert
Iterating
x is a pair (key, value).
Search
C++20 and after:
Before:
Set
Prefer std::unordered_set over std::set.
Initialization
From literals:
Membership
Returns 1 if element exists, 0 otherwise. Faster than .find().
Remove
Remove entry (in-place):
Tuples
Include:
Initialization
or:
Access
std::get<n>. Example:
Concatenate
std::tuple_cat. Example:
Variadic
Using std::apply, lambdas and variadic. Example: handle tuple in a generic fashion:
Vector
Initialization
Iterate
Empty
Size
Slice
Getting a subset of a vector for index a to index b:
If b = v.size() -1:
Passing as parameter
Memory
Shared Pointers
Creating pointers:
De-referencing is the same as a regular pointer:
Placement New
Allows pre-allocating into a larger chunk of memory into a buffer and then newing objects into that memory.
Note that deletion is not performed for the placement new, only for the original buffer.
Flow Control
Conditionals
Initialize and evaluate inline:
Exceptions
Basic try/catch:
Custom exception:
Object-Oriented
Class
Constructor
Defining constructor outside class definition:
Explicit initialization:
Destructor
Instantiate
When to use new:
Methods
Read-only method. Add const after function signature.
Static Member Variables
Shared across instances.
Inheritance
Visibility
One of public|protected|private (default is private). Makes all methods from Base the most restrictive between the inheritance visibility and the original method visibility.
For struct the inheritance mode is public by default.
Abstract methods
If you’re coming from Java, C++ version of abstract methods are pure virtual methods.
Interface
If you’re coming from Java, C++ doesn’t have syntax for interfaces but it can be modeled as class with all pure virtual methods.
Note that we need to define the virtual destructor in this case.
Override methods
By default C++ binds the methods to the type, even if it was re-implemented in the derived class. Example:
In g(), f() is bound to Base (type) not to Child (instance). To change this behavior, f() must be virtual in Base:
It’s a good practice to add override so that the compiler catches this subtlety:
You can also add override when implementing pure virtual methods.
Templates
Function
Class
Inner Type
It’s possible to access the type of a template:
Specialization
Type alias
Implementation
In this setup the generic class acts almost like a interface.
Variadic
The generic class can use typename ...T to allow specialization by any number of types:
Compile Time
Static Assert
Syntax:
Where <expr> must be a constant expression.
Constant Expressions
Syntax
Function:
Class member:
Type Traits
The working unit of a type trait is the type trait std::integral_constant, which wraps a constant and its type. Example:
Access the value:
A boolean type trait is so common it has its own alias:
Type Equality (=)
Done via std::is_same():
Conjunction (&&)
Check multiple types: std::conjunction(). It expects one or more std::bool_constant types:
Files
Check if file exists
Works for directories too.
Create directory
Create temporary file name
Read from file
Write to file
Date and Time
Time
Duration
Structure: std::chrono::duration<Rep, Period>. Rep is the underlying type, e.g. double or int. Period is a rational number (std::ratio) indicating the relative scale factor to 1 second and is only relevant when converting between units.
Examples
Helper duration types
The actual underlying Rep for these types is open for compilers to determine but the spec dictates signed integers of a minimum size (shown in parenthesis below, in bits).
Type
Bits
std::chrono::nanoseconds
64
std::chrono::microseconds
55
std::chrono::milliseconds
45
std::chrono::seconds
35
std::chrono::minutes
29
std::chrono::hours
23
Some of the examples from above simplified:
Get value from duration
It always returns the value in the scale defined by Period, so basically the value we passed when constructing it:
When values are captured via copy they’re const. To change it use mutable:
Return types are inferred but they can be provided explicitly:
Passing Function As Parameter
Lambda:
Class method:
Namespaces
Empty Namespace
Keywords: anonymous, unnamed
This makes x local to the file and doesn’t risk being exposed if some other file includes it.
Nested namespace
Which is equivalent to
Namespace aliasing
Namespace resolution
Suppose we’re in namespace a::b, and inside it we refer to a variable x via c::x. What namespace does the compiler search in?
Search for the first namespace matching a::b::c.
If not found, search for a namespace matching a::c.
If not found, search for a namespace matching c.
Once if has a namespace, use the x defined there. Report error if not. The key insight is that it binds to a namespace before searching for symbols there, so this case:
Will lead to a compilation error since it binds to a::b::c first, even though xis defined in a::c. If we comment the first line it works.