As posted in C++ Then and Now, Modern C++11
feels like a new language. There are plenty of resources online which explain Modern C++
features. This is different in how it is organized. It’s a list that you can approach and adopt/learn incrementally without getting overwhelmed by the large set of new features.
The descriptions are intentionally short to keep the features as an easily accessible list. Much of the details can be easily found online. References are listed besides some features and the full list is in the references section at the bottom.
Deprecated
Language
Library
References
C++
and C++11
are used interchangeably. Both refer to the standards published in C++11
, C++14
, C++17
and C++20
.Deprecated
C++11
is backward compatible, except for a minor set of deprecated features which may/will be removed in the future. It is best to ensure that these constructs are purged from your code base sooner than later. Most are deprecated in C++11
and removed in C++17
or C++20
.
export |
Used to mark a template definition exported. In C++11 see related extern template . In C++20 see related to modules. |
register |
Automatic storage duration specifier. In C++11 , the keyword is reserved and unused. |
throw() [8] |
Dynamic exception specification. In C++11 , see related noexcept . |
std::auto_ptr |
Legacy smart pointer. In C++11 , see related to smart pointers, particularly std::unique_ptr . |
std::unary_function |
Base class for function objects. In C++11 , see the more general std::function . |
std::bind1st |
Binds the argument(s) to the parameter of a function object. In C++11 , see std::bind . |
std::ptr_fun |
Creates a function wrapper object. In C++11 , see the more general std::function and std::ref . |
std::mem_fun |
Creates a member function wrapper object. In C++11 , see std::mem_fn . |
Implicit lambda capture of this using [=] |
In C++20 prefer capturing explicitly using [=, this] or [=, *this] . |
Headers<ccomplex> <ciso646> <cstdalign> <cstdbool> <ctgmath> |
In C++20 , the corresponding headers remain for compatibility with C . |
Language
General features that improve code readability and type safety. The underlying compiler implementation may be significant (e.g. auto
) but the implication for the programmer is straight forward.
Angle brackets | Compiler recognizes between operator and typedef without having to add whitespace. |
nullptr |
Designed to replace NULL macro. Can be implicitly converted into pointer types, and unlike NULL , not convertible to integral types except bool . |
auto |
Automatic compiler deduction of variable and return types according to the type. Particularly useful for long template declarations. |
Range based for loop |
Executes the for loop over a range, a more readable equivalent of the traditional syntax. |
if with initializerswitch with initializerrange based for with initializer |
New versions of the if , switch and range based for statements which simplify common code patterns and keep scopes tight. |
class enum |
Strongly typed enum to fix C-style enum problems like implicit conversions, inability to specify the underlying type and scope pollution. Supports forward declaration. Supports direct list initialization. |
using |
Type alias which is semantically similar to a typedef , which is easier to read and compatible with templates.Introduces the named enumerator members into the scope, similar to namespace . |
Nested namespace | Using the namespace resolution operator to create compact nested namespace definitions.namespace A::B::C {...} |
Digit separator | Optional single quotes may be inserted between the digits as a separator, which are ignored by the compiler.int i = 1'000'000; |
Binary literal | A prefix to represent binary digits similar to octal and hex.int d = 42; // integer |
Raw string literal | Prefix R"()" used to avoid escaping of any character. |
UTF string literals | Prefix for UTF encoded string literal.u8 = char8_t |
Attributes | Attributes provide a standard syntax over compiler specific __attribute__(...) , __declspec , etc.The attributes specified by the standard are [[noreturn]] |
3-way comparison operator <=> |
Takes two values A and B belonging to a type and determines whether A < B, A = B, or A > B in a single operation. |
Feature test macros | Set of preprocessor macros corresponding to C++ language and library features introduced in C++11 or later. They are intended as a simple and portable way to detect the presence of said features. |
Aggregate initialization Designated initializers |
Initializes an aggregate from braced-init-list. Supports C-style designated initializer syntax. |
Classes which are the basis of encapsulation in C++ get much needed improvements that make the code cleaner and safer. It fits really well with the existing constructs.
Delegating constructor | Constructors can call other constructors in the same class using an initializer list. Prior to C++11 , this was achieved by having a common initializer member function. |
Inherited constructor [10] | The using directive “inherits” the base class constructors.Prior to C++11 , this was achieved by writing a matching constructor in the derived class and invoking the appropriate base class constructor. |
Converting constructor | All constructors without the explicit specifier are considered for implicit conversion.Prior to C++11 , it was restricted to only constructors without the explicit specifier and with a single parameter. |
explicit(bool) |
Implicit conversion (converting constructor or user defined conversion function) can be restricted by using the explicit specifier. Also can conditionally select at compile-time whether it is made explicit or not. |
Non-static data member initializers |
Non-static data members can be initialized where they are declared, potentially cleaning up constructors of default initializations. |
=delete |
Explicitly specify that a function should not be implemented or invoked. Particularly useful to restrict compiler generated member functions. Prior to C++11 , the approach was to make the functions private . |
=default |
Explicitly specify/request the compiler to generate the default function implementation. |
override |
Explicitly specify that a virtual function overrides another virtual function. |
final |
Specify that a virtual function cannot be overridden in a derived class. Specify that a class cannot be derived further. |
Special member functions | Additional member functions, move constructor and move assignment aperator, to support move semantics. |
These are some not so obvious features but reasonably easy to grasp and leverage.
inline variable |
A variable declared inline has the same semantics as a function declared inline . |
inline namespace |
All members of an inline namespace are treated as if they were part of its parent namespace. |
constexpr [11][12] |
Specifies a variable or function as constant expression, which is evaluated by the compiler at compile-time. It provides a type safe alternative to macros. |
consteval |
Similar to constexpr functions, but functions with a consteval specifier must produce a constant. These are called immediate functions. |
constinit |
Indicates that a variable has static initialization. |
User defined literalsstd literals
|
Allows integer, floating-point, character, and string literals to produce objects of user-defined type by defining a user defined suffix. It allows creation of literals like 12_km, 0.5_Pa, 10_celsius .A suffix that does not begin with the underscore is reserved for the literal operators provided by the standard library, which include built-in literals for std::chrono and std::basic_string . |
static_assert |
Assertions that are evaluated at compile-time. Particularly useful in generic/template programming. It’s quite powerful in conjunction with the STL type_traits . |
noexcept |
Functions that guarantee they won’t emit exceptions. |
decltype [13] |
Operator which returns the declared type of an expression passed to it. Use std::declval for member functions in decltype expressions without the need to go through constructors. |
alignof |
Returns the alignment, in bytes, required for any instance of the type indicated by type-id. |
alignas |
The byte alignment specifier may be applied to the declaration of a type. |
Trailing return type [14] | An alternative syntax for writing function declarations. Instead of putting the return type before the name of the function, in the new syntax, it is written after the parameters with the -> symbol. |
Generic programming with templates have improvements, which have long been pain points but the topics listed here are not necessarily exhaustive.
extern template |
Indicates to the compiler not to instantiate a template as it will be explicitly done elsewhere. |
Template argument deduction | To instantiate a function or class template, every template argument must be known, but not every template argument need to be specified. |
auto as non-type template parameter |
Type can be deduced from the passed in argument. |
class type in non-type template parameter | Class types are allowed as non-type template parameter. |
Variable template | Defines a family of variables or static data members. |
Variadic template | Accepts zero or more template arguments. |
Folding expressions | Reduces (folds) a parameter pack over a binary operator. |
These are the big-name features of Modern C++, which require time and patience to learn. They are not necessarily difficult to use, but it is important to recognize the underlying concepts to fully comprehend and appreciate them. So do take the time to understand the fundamentals.
Uniform initialization | Using braces {} as a single initialization syntax. |
rvalue reference [15] | The pre C++11 reference is now called lvalue reference. The rvalue reference is required for move semantics and perfect forwarding. |
Ref qualified member functions [16][17] | Calling a function on a rvalue object. |
Move semanticsstd::move |
Move semantics is mostly about performance optimization, the ability to move an object without the expensive overhead of copying. |
Perfect forwardingstd::forward |
Passing arguments from one function to another without any overhead. |
Lambda expression | Convenient way to create function objects and unnamed/anonymous callback functions. |
Structured binding [18] | Binds the specified names to subobjects or elements of the initializer. Ability to declare multiple variables initialised from a tuple or struct. |
Memory model | Defines the semantics of computer memory storage for the purpose of the C++ abstract machine. |
Garbage Collection ABI [20] | Provides a definition of what a Garbage Collection can do if one is used and an ABI (Application Binary Interface) to help control its actions. |
Conceptsconcept |
Concepts are named compile-time predicates which constrain types. The requires keyword is used either to start a requires clause or a requires expression. |
Coroutinesco_await |
A coroutine is a function that can suspend execution to be resumed later. |
Modulesmodule |
Modules help divide large amounts of code into logical parts. |
Modern C++
continues to provide compatibility with C
.
Updated POD definition | The POD (Plain Old Data) type, which is compatible with C , can be of trivial or standard layout type. |
C99 compatibility |
Adopted many (though not all) of C99 features. |
Library
Simple much required string utilities.
std::to_string std::to_wstring |
Converts a numeric argument to a string. |
std::string_view |
A non-owning reference to a string. Useful for providing an abstraction on top of strings (e.g. for parsing). |
|
Checks if the string begins or ends with the given substring. |
<format> |
Text formatting offers a safe and extensible alternative to the printf family of functions. |
Containers and related features which make the library more complete.
std::initializer_list |
A lightweight array-like container of elements created using a braced list syntax. |
std::array |
Container built on top of a C-style array |
std::tuple |
Tuples are a fixed-size collection of heterogeneous values. Works in conjunction with std::tie , std::get and std::ignore. |
std::unordered_set |
Associative container sorted in no particular order. |
<span> |
A view (i.e. non-owning) of a container providing bounds-checked access to a contiguous group of elements. |
<ranges> |
Uniform composable operations on containers. |
std::erase std::erase_if |
Uniform container erasure. |
contains() |
Member function on associative container to check if it has an element. |
These are much needed library features that should eliminate propietary implemenations.
Smart pointersstd::unique_ptr std::shared_ptr std::weak_ptr std::make_unique std::make_shared |
Smart pointers are wrappers around raw pointers that act much like the raw pointers they wrap, but that avoid many of their pitfalls. std::auto_ptr is deprecated. |
<filesystem> |
Standard way to manipulate files, directories, and paths in a file system. |
<chrono> |
Utility functions and types that deal with durations, clocks, and time points. |
<random> |
Pseudo-random number generation. Compile-time rational arithmetic. Mathematical constants including PI, Euler’s number, etc. |
<regex> |
Regex library for pattern matching. |
<type_traits> |
Defines a compile-time template-based interface to query or modify the properties of types. |
<atomic> Atomic smart pointers |
Provides components for fine-grained atomic operations allowing for lockless concurrent programming. |
Concurrency<thread> |
Standard replacement for platform dependent threading library (e.g. pthreads, windows threads). |
<concepts> |
Support for concepts. |
<coroutine> |
Support for coroutines. |
<bit> |
Support for bit operations. |
<source_location> |
A class representing information about the source code, such as file names, line numbers, and function names. |
<version> |
Supplies implementation dependent information about the standard library. |
Generic types that provide type safety.
std::any |
Type-safe container for single values of any type. |
std::optional [23] |
Manages an optional contained value, that is, a value that may or may not be present. A common use case for optional is the return value of a function that may fail. |
std::variant |
Represents a type-safe union. An instance of std::variant at any given time holds a value of one of its alternative types (it’s also possible for it to be valueless). |
std::byte |
Distinct type that implements the concept of byte. |
General purpose wrappers and utilities for Callable and Function objects.
std::function |
Store, copy and invoke any Callable target — functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members. |
std::bind |
Binds one or more arguments to a function object. |
std::bind_front |
Binds arguments to the first n parameters. |
std::placeholders |
Namespace contains the placeholder objects [_1, . . . _N] . When used as an argument in std::bind , it acts as a stand-in for unbound arguments. |
std::invoke |
Invoke the Callable object with the given parameter arguments. |
std::apply |
Invoke the Callable object with the given tuple of arguments. |
std::mem_fn |
Generates wrapper objects for pointers to members, which can store, copy, and invoke a pointer to member. |
std::ref std::cref |
Helper functions that generate an object of type std::reference_wrapper . Used to pass objects by reference to std::bind . |
std::reference_wrapper |
Wraps a reference in a copyable and assignable object. |
New algorithms for a variety of purposes (e.g. searching, sorting, counting, manipulating) that operate on ranges of elements.
Execution policies | Most algorithms have overloads that accept execution policies to support different types of parallel execution. |
std::all_of std::any_of std::none_of |
Predicate check for containers |
std::find_if_not |
Extensions to existing std::find |
std::copy_i std::copy_n |
Extensions to existing std::copy |
std::move std::move_backward |
Move ranges |
std::random_shuffle std::shuffle |
Randomly re-orders elements in a range |
std::sample |
Selects n random elements from a sequence |
std::is_partitioned std::partition_copy std::partition_point |
Extension to partitioning operations |
std::is_sorted std::is_sorted_until std::is_heap std::is_heap_until std::is_permutation |
Checks for heaps, permutations and sorted ranges |
std::minmax std::minmax_element |
Retrieve min and max element as a pair in one call. |
std::clamp |
Clamps a value between a pair of boundary values |
std::iota |
Range of successive increments |
std::midpoint |
Computes the midpoint of the integers, floating-points, or pointers. |
std::lerp |
Linear interpolation and extrapolation at paramter t. |
std::reduce std::transform_reduce |
Out of order reduction |
std::uninitialized_* std::destroy* |
Operations on uninitialized memory |
References
- isocpp.org: C++ FAQ
- cppreference.com
- Wikipedia: C++11
- Bjarne Stroustrup: C++11 – the new ISO C++ standard
- Cheatsheet of modern C++ language and library features
- C++17 Features
- Scott Meyers: Effective Modern C++
- Don’t use exception specifications
- Don’t use
auto
unless you mean it - Inherited constructors
- Using
constexpr
- Convert macros to
constexpr
decltype
andstd::declval
- Pros and Cons of Alternative Function Syntax in C++
- A Brief Introduction to Rvalue References
- Ref qualifiers
- Introducing ref-qualifiers for member functions
- Structured Bindings
- Structured Bindings, Template Argument Deduction and Selection Initialization
- Garbage collection ABI
- What’s the difference between C++ and C?
- Make your functions functional
- Clearer interfaces with
std::optional
- cppreference.com: Algorithms Library
- Clang: Modules
- Modules