# Top Modern C++ Features (an abridged ad-hoc list) Note: most of this document is pulled from resources at [cppreference.com](https://en.cppreference.com/w/). See pages like [C++11](https://en.cppreference.com/w/cpp/11), [C++14](https://en.cppreference.com/w/cpp/14), [C++17](https://en.cppreference.com/w/cpp/17), [C++20](https://en.cppreference.com/w/cpp/20) for a good summary changelog of each specific C++ specification. Certain topics are linked elsewhere when the site provides a more thorough explanations of a given feature. ## RAII If you have not already read about ["RAII"](https://en.cppreference.com/w/cpp/language/raii) (Resource Acquisition is Initialization), do so first. RAII controls the lifetime of an object, aka when pointers get destructed, when files get closed, when locks or resources get released, and so on. RAII is not a change to the language, so it's not technically "modern", but it is a fundamental concept of all modern STL objects as well as a conventional expectation in modern C++ that your code is "RAII-compliant". It is core to understanding how many new STL features are built. ## Syntax additions - [`auto`](https://www.geeksforgeeks.org/type-inference-in-c-auto-and-decltype/) keyword for type decl inference (C++11) - [Lambdas](https://www.geeksforgeeks.org/lambda-expression-in-c/) for inline blocks (C++11/14) - [Ranged based loops](https://www.geeksforgeeks.org/range-based-loop-c/) aka "for-each" syntax (C++11) - [Structured binding declaration](https://en.cppreference.com/w/cpp/language/structured_binding) is similar to "splat" operation in Ruby/Python. Directly assign a "tuple" (see STL changes below) into multiple variables. (C++17) - [Aggregate initialization](https://en.cppreference.com/w/cpp/language/aggregate_initialization) (`Person p = {"John"}` or `{.name = "John"}`) (C++11 for list, C++20 for direct) - [if allows an initializer before the condition](https://www.tutorialspoint.com/cplusplus17-if-statement-with-initializer) now. (C++17) - [constexpr](https://www.geeksforgeeks.org/user-defined-literals-cpp/) for constant computable values (in lieu of `#define`) (C++11) - [User defined literals](https://www.geeksforgeeks.org/user-defined-literals-cpp/) for type suffixes like `10sec` etc (C++11) - [`final`](https://en.cppreference.com/w/cpp/language/final), [`override`](https://en.cppreference.com/w/cpp/language/override) and [`nullptr`](https://en.cppreference.com/w/cpp/language/nullptr) are keywords now (C++11) - [`mutable`](https://www.geeksforgeeks.org/c-mutable-keyword/) declares fine-grained write access to otherwise-const objects/functions (C++11) - [`thread_local`](https://en.cppreference.com/w/cpp/language/storage_duration) can be used to separate variable access across threads (C++11) - [Concepts](https://www.cppfiddler.com/2019/06/09/concept-based-interfaces/) are an _advanced_ way to express "interface" types (C++20) ## STL additions (a very abridged grab-bag) ### Smart pointers - [A "deprecated" overview of the pointers](https://en.cppreference.com/book/intro/smart_pointers) - [`std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr) (C++11) and [`std::make_unique`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique) (C++14) for managing lifetime of dynamically allocated objects with only 1 owner/accessor at a time - [`std::shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr) (C++11) and [`std::make_shared`](https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared) (C++14) for managing lifetime of dynamically allocated objects with many object owners. - [`std::swap`](https://en.cppreference.com/w/cpp/algorithm/swap) and [`std::move`](https://en.cppreference.com/w/cpp/algorithm/move) are also useful to look at to understand ownership changes (C++11) ### Functional programming - [`std::function`](https://www.cplusplus.com/reference/functional/function/) is the high-level type you use to receive lambdas/function pointers aka callbacks (C++11) - [`std::bind`](https://www.cplusplus.com/reference/functional/bind) generates a "bound" function that can add additional parameters to a function callback. Necessary if you want to pass an object method as a callback and need the `this` context bound. See also "placeholders" (defined in the article). (C++11) ### Threads and data access management - [`std::thread`](https://www.geeksforgeeks.org/multithreading-in-cpp/) is a standardized platform-independent implementation to launch platform threads (POSIX, etc) (C++11) - [`std::atomic`](https://www.cplusplus.com/reference/atomic/atomic/) is a container type that can be used on most primitive types (ints, bools) to allow for race-free access without needing mutexes. Use this first if you're dealing with primitive data. (C++11) - [`std::mutex`](https://en.cppreference.com/w/cpp/thread/mutex) and [`std::recursive_mutex`](https://en.cppreference.com/w/cpp/thread/recursive_mutex) for data access synchronization across threads (C++11) - [`std::scoped_lock`](https://en.cppreference.com/w/cpp/thread/scoped_lock) (C++17) and [`std::unique_lock`](https://en.cppreference.com/w/cpp/thread/unique_lock) (C++11) for locking thread access on mutexes (RAII lock management) ### Async support - [`std::async`](https://www.cplusplus.com/reference/future/async/) for an abstraction on threading. Does work "later" without worrying about whether it's done on a thread or runloop or process etc. (C++11) - [`std::future`](https://www.cplusplus.com/reference/future/future/) is what an async call returns. It is the abstraction of the "work being done". (C++11) - [`std::promise`](https://www.cplusplus.com/reference/future/promise/) even more abstraction on futures. Since promises rely on futures quite explicitly and don't necessarily add new behavior, futures are usually all you need. (C++11) ### High level containers - [`std::tuple`](https://en.cppreference.com/w/cpp/utility/tuple) allows creating lists of heterogeneous objects for arguments or return types without defining an explicit struct to hold them all. Ex: `auto [a, b] = std::tuple{1, true};` (C++11) - [`std::optional`](https://en.cppreference.com/w/cpp/utility/optional) is a way to express "nullable" types without requiring pointers. (C++17) - [`std::variant`](https://riptutorial.com/cplusplus/example/18604/basic-std--variant-use) is the modern way to express a "union" aka polymorphic value. (C++17) ### String/IO manipulations - [``](https://www.softwaretestinghelp.com/regex-in-cpp/) is now a standardized library header (C++11) - [``](https://en.cppreference.com/w/cpp/filesystem) header standardizes filesystem operations across platforms, as well as the specifics of path representation via [`std::filesystem::path`](https://en.cppreference.com/w/cpp/filesystem/path). (C++17 but also available in Boost) - [`std::string_view`](https://www.learncpp.com/cpp-tutorial/an-introduction-to-stdstring_view/) ([more detail](https://devblogs.microsoft.com/cppblog/stdstring_view-the-duct-tape-of-string-types/)) is going to (eventually) take over as the abstracted "string interface" type, allowing for u8, u16, or u32 string types to be passed around without needing direct knowledge about internals. (C++17) ### Chrono / Time - In general, [``](https://en.cppreference.com/w/cpp/header/chrono) provides a ton of new time abstractions. (C++11-20) - [`std::chrono::duration`](https://en.cppreference.com/w/cpp/chrono/duration) for expressing time in ms, secs, days, etc. (`std::chrono::milliseconds(16)`). (C++11) - [`std::literals::chrono_literals`](https://en.cppreference.com/w/cpp/chrono/operator%22%22ms) is where literal operators are defined, i.e. `250ms`, `10min`, etc. (C++14) - [`std::steady_clock`](https://en.cppreference.com/w/cpp/chrono/steady_clock) and [`std::high_resolution_clock`](https://en.cppreference.com/w/cpp/chrono/high_resolution_clock) for standardized access to getting clock time. (C++11) - [`` changes in C++20](https://mariusbancila.ro/blog/2018/03/27/cpp20-calendars-and-time-zones/) specifically add a lot more support for calendar/timezone calculations and parsing/formatting.