You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/cpp/welcome-back-to-cpp-modern-cpp.md
+28-28Lines changed: 28 additions & 28 deletions
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
---
2
2
title: "Welcome back to C++ - Modern C++"
3
3
description: "Describes the new programming idioms in Modern C++ and their rationale."
4
-
ms.date: "01/10/2020"
4
+
ms.date: "05/17/2020"
5
5
ms.topic: "conceptual"
6
6
ms.assetid: 1cb1b849-ed9c-4721-a972-fd8f3dab42e2
7
7
---
@@ -11,13 +11,13 @@ Since its creation, C++ has become one of the most widely used programming langu
11
11
12
12
One of the original requirements for C++ was backward compatibility with the C language. As a result, C++ has always permitted C-style programming, with raw pointers, arrays, null-terminated character strings, and other features. They may enable great performance, but can also spawn bugs and complexity. The evolution of C++ has emphasized features that greatly reduce the need to use C-style idioms. The old C-programming facilities are there when you need them, but with modern C++ code you should need them less and less. Modern C++ code is simpler, safer, more elegant, and still as fast as ever.
13
13
14
-
The following sections provide an overview of the main features of modern C++. Unless noted otherwise, the features listed here are available in C++11 and later. In the Microsoft C++ compiler, you can set the [/std](../build/reference/std-specify-language-standard-version.md) compiler option to specify which version of the standard to use for your project.
14
+
The following sections provide an overview of the main features of modern C++. Unless noted otherwise, the features listed here are available in C++11 and later. In the Microsoft C++ compiler, you can set the [`/std`](../build/reference/std-specify-language-standard-version.md) compiler option to specify which version of the standard to use for your project.
15
15
16
16
## Resources and smart pointers
17
17
18
-
One of the major classes of bugs in C-style programming is the *memory leak*. Leaks are often caused by a failure to call **delete** for memory that was allocated with **new**. Modern C++ emphasizes the principle of *resource acquisition is initialization* (RAII). The idea is simple. Resources (heap memory, file handles, sockets, and so on) should be *owned* by an object. That object creates, or receives, the newly allocated resource in its constructor, and deletes it in its destructor. The principle of RAII guarantees that all resources get properly returned to the operating system when the owning object goes out of scope.
18
+
One of the major classes of bugs in C-style programming is the *memory leak*. Leaks are often caused by a failure to call **`delete`** for memory that was allocated with **`new`**. Modern C++ emphasizes the principle of *resource acquisition is initialization* (RAII). The idea is simple. Resources (heap memory, file handles, sockets, and so on) should be *owned* by an object. That object creates, or receives, the newly allocated resource in its constructor, and deletes it in its destructor. The principle of RAII guarantees that all resources get properly returned to the operating system when the owning object goes out of scope.
19
19
20
-
To support easy adoption of RAII principles, the C++ Standard Library provides three smart pointer types: [std::unique_ptr](../standard-library/unique-ptr-class.md), [std::shared_ptr](../standard-library/shared-ptr-class.md), and [std::weak_ptr](../standard-library/weak-ptr-class.md). A smart pointer handles the allocation and deletion of the memory it owns. The following example shows a class with an array member that is allocated on the heap in the call to `make_unique()`. The calls to **new** and **delete** are encapsulated by the `unique_ptr` class. When a `widget` object goes out of scope, the unique_ptr destructor will be invoked and it will release the memory that was allocated for the array.
20
+
To support easy adoption of RAII principles, the C++ Standard Library provides three smart pointer types: [`std::unique_ptr`](../standard-library/unique-ptr-class.md), [`std::shared_ptr`](../standard-library/shared-ptr-class.md), and [`std::weak_ptr`](../standard-library/weak-ptr-class.md). A smart pointer handles the allocation and deletion of the memory it owns. The following example shows a class with an array member that is allocated on the heap in the call to `make_unique()`. The calls to **`new`** and **`delete`** are encapsulated by the `unique_ptr` class. When a `widget` object goes out of scope, the unique_ptr destructor will be invoked and it will release the memory that was allocated for the array.
21
21
22
22
```cpp
23
23
#include<memory>
@@ -42,20 +42,20 @@ void functionUsingWidget() {
42
42
43
43
Whenever possible, use a smart pointer when allocating heap memory. If you must use the new and delete operators explicitly, follow the principle of RAII. For more information, see [Object lifetime and resource management (RAII)](object-lifetime-and-resource-management-modern-cpp.md).
44
44
45
-
## std::string and std::string_view
45
+
## `std::string` and `std::string_view`
46
46
47
-
C-style strings are another major source of bugs. By using [std::string and std::wstring](../standard-library/basic-string-class.md), you can eliminate virtually all the errors associated with C-style strings. You also gain the benefit of member functions for searching, appending, prepending, and so on. Both are highly optimized for speed. When passing a string to a function that requires only read-only access, in C++17 you can use [std::string_view](../standard-library/basic-string-view-class.md) for even greater performance benefit.
47
+
C-style strings are another major source of bugs. By using [`std::string` and `std::wstring`](../standard-library/basic-string-class.md), you can eliminate virtually all the errors associated with C-style strings. You also gain the benefit of member functions for searching, appending, prepending, and so on. Both are highly optimized for speed. When passing a string to a function that requires only read-only access, in C++17 you can use [`std::string_view`](../standard-library/basic-string-view-class.md) for even greater performance benefit.
48
48
49
-
## std::vector and other Standard Library containers
49
+
## `std::vector` and other Standard Library containers
50
50
51
-
The Standard Library containers all follow the principle of RAII. They provide iterators for safe traversal of elements. And, they're highly optimized for performance and have been thoroughly tested for correctness. By using these containers, you eliminate the potential for bugs or inefficiencies that might be introduced in custom data structures. Instead of raw arrays, use [vector](../standard-library/vector-class.md) as a sequential container in C++.
51
+
The standard library containers all follow the principle of RAII. They provide iterators for safe traversal of elements. And, they're highly optimized for performance and have been thoroughly tested for correctness. By using these containers, you eliminate the potential for bugs or inefficiencies that might be introduced in custom data structures. Instead of raw arrays, use [`vector`](../standard-library/vector-class.md) as a sequential container in C++.
52
52
53
53
```cpp
54
54
vector<string> apples;
55
55
apples.push_back("Granny Smith");
56
56
```
57
57
58
-
Use [map](../standard-library/map-class.md) (not `unordered_map`) as the default associative container. Use [set](../standard-library/set-class.md), [multimap](../standard-library/multimap-class.md), and [multiset](../standard-library/multiset-class.md) for degenerate and multi cases.
58
+
Use [`map`](../standard-library/map-class.md) (not `unordered_map`) as the default associative container. Use [`set`](../standard-library/set-class.md), [`multimap`](../standard-library/multimap-class.md), and [`multiset`](../standard-library/multiset-class.md) for degenerate and multi cases.
When performance optimization is needed, consider using:
67
67
68
-
- The [array](../standard-library/array-class-stl.md) type when embedding is important, for example, as a class member.
68
+
- The [`array`](../standard-library/array-class-stl.md) type when embedding is important, for example, as a class member.
69
69
70
-
- Unordered associative containers such as [unordered_map](../standard-library/unordered-map-class.md). These have lower per-element overhead and constant-time lookup, but they can be harder to use correctly and efficiently.
70
+
- Unordered associative containers such as [`unordered_map`](../standard-library/unordered-map-class.md). These have lower per-element overhead and constant-time lookup, but they can be harder to use correctly and efficiently.
71
71
72
72
- Sorted `vector`. For more information, see [Algorithms](../cpp/algorithms-modern-cpp.md).
73
73
@@ -79,15 +79,15 @@ Before you assume that you need to write a custom algorithm for your program, fi
79
79
80
80
Here are some important examples:
81
81
82
-
-**for_each**, the default traversal algorithm (along with range-based for loops).
82
+
-`for_each`, the default traversal algorithm (along with range-based `for` loops).
83
83
84
-
-**transform**, for not-in-place modification of container elements
84
+
-`transform`, for not-in-place modification of container elements
85
85
86
-
-**find_if**, the default search algorithm.
86
+
-`find_if`, the default search algorithm.
87
87
88
-
-**sort**, **lower_bound**, and the other default sorting and searching algorithms.
88
+
-`sort`, `lower_bound`, and the other default sorting and searching algorithms.
89
89
90
-
To write a comparator, use strict **<** and use *named lambdas* when you can.
90
+
To write a comparator, use strict **`<`** and use *named lambdas* when you can.
91
91
92
92
```cpp
93
93
auto comp = [](const widget& w1, const widget& w2)
C++11 introduced the [auto](auto-cpp.md) keyword for use in variable, function, and template declarations. **auto** tells the compiler to deduce the type of the object so that you don't have to type it explicitly. **auto** is especially useful when the deduced type is a nested template:
103
+
C++11 introduced the [`auto`](auto-cpp.md) keyword for use in variable, function, and template declarations. **`auto`** tells the compiler to deduce the type of the object so that you don't have to type it explicitly. **`auto`** is especially useful when the deduced type is a nested template:
104
104
105
105
```cpp
106
106
map<int,list<string>>::iterator i = m.begin(); // C-style
107
107
auto i = m.begin(); // modern C++
108
108
```
109
109
110
-
## Range-based for loops
110
+
## Range-based `for` loops
111
111
112
-
C-style iteration over arrays and containers is prone to indexing errors and is also tedious to type. To eliminate these errors, and make your code more readable, use range-based for loops with both Standard Library containers and raw arrays. For more information, see [Range-based for statement](../cpp/range-based-for-statement-cpp.md).
112
+
C-style iteration over arrays and containers is prone to indexing errors and is also tedious to type. To eliminate these errors, and make your code more readable, use range-based `for` loops with both Standard Library containers and raw arrays. For more information, see [Range-based `for` statement](../cpp/range-based-for-statement-cpp.md).
113
113
114
114
```cpp
115
115
#include<iostream>
@@ -133,9 +133,9 @@ int main()
133
133
}
134
134
```
135
135
136
-
## constexpr expressions instead of macros
136
+
## `constexpr` expressions instead of macros
137
137
138
-
Macros in C and C++ are tokens that are processed by the preprocessor before compilation. Each instance of a macro token is replaced with its defined value or expression before the file is compiled. Macros are commonly used in C-style programming to define compile-time constant values. However, macros are error-prone and difficult to debug. In modern C++, you should prefer [constexpr](constexpr-cpp.md) variables for compile-time constants:
138
+
Macros in C and C++ are tokens that are processed by the preprocessor before compilation. Each instance of a macro token is replaced with its defined value or expression before the file is compiled. Macros are commonly used in C-style programming to define compile-time constant values. However, macros are error-prone and difficult to debug. In modern C++, you should prefer [`constexpr`](constexpr-cpp.md) variables for compile-time constants:
139
139
140
140
```cpp
141
141
#defineSIZE 10 // C-style
@@ -181,11 +181,11 @@ For more information, see [Brace initialization](initializing-classes-and-struct
181
181
182
182
## Move semantics
183
183
184
-
Modern C++ provides *move semantics*, which make it possible to eliminate unnecessary memory copies. In earlier versions of the language, copies were unavoidable in certain situations. A *move* operation transfers ownership of a resource from one object to the next without making a copy. When implementing a classthat owns a resource (such as heap memory, file handles, and so on), you can define a *move constructor* and *move assignment operator* for it. The compiler will choose these special members during overload resolution in situations where a copy isn't needed. The Standard Library container types invoke the move constructor on objects if one is defined. For more information, see [Move Constructors and Move Assignment Operators (C++)](move-constructors-and-move-assignment-operators-cpp.md).
184
+
Modern C++ provides *move semantics*, which make it possible to eliminate unnecessary memory copies. In earlier versions of the language, copies were unavoidable in certain situations. A *move* operation transfers ownership of a resource from one object to the next without making a copy. Some classes own resources such as heap memory, file handles, and so on. When you implement a resource-owning class, you can define a *move constructor* and *move assignment operator* for it. The compiler chooses these special members during overload resolution in situations where a copy isn't needed. The Standard Library container types invoke the move constructor on objects if one is defined. For more information, see [Move Constructors and Move Assignment Operators (C++)](move-constructors-and-move-assignment-operators-cpp.md).
185
185
186
186
## Lambda expressions
187
187
188
-
In C-style programming, a function can be passed to another function by using a *function pointer*. Function pointers are inconvenient to maintain and understand. The function they refer to may be defined elsewhere in the source code, far away from the point at which it's invoked. Also, they're not type-safe. Modern C++ provides *function objects*, classes that override the [()](function-call-operator-parens.md) operator, which enables them to be called like a function. The most convenient way to create function objects is with inline [lambda expressions](../cpp/lambda-expressions-in-cpp.md). The following example shows how to use a lambda expression to pass a function object, that the `for_each` function will invoke on each element in the vector:
188
+
In C-style programming, a function can be passed to another function by using a *function pointer*. Function pointers are inconvenient to maintain and understand. The function they refer to may be defined elsewhere in the source code, far away from the point at which it's invoked. Also, they're not type-safe. Modern C++ provides *function objects*, classes that override the [`operator()`](function-call-operator-parens.md) operator, which enables them to be called like a function. The most convenient way to create function objects is with inline [lambda expressions](../cpp/lambda-expressions-in-cpp.md). The following example shows how to use a lambda expression to pass a function object, that the `for_each` function will invoke on each element in the vector:
189
189
190
190
```cpp
191
191
std::vector<int> v {1,2,3,4,5};
@@ -200,13 +200,13 @@ The lambda expression `[=](int i) { return i > x && i < y; }` can be read as "fu
200
200
201
201
Modern C++ emphasizes exceptions rather than error codes as the best way to report and handle error conditions. For more information, see [Modern C++ best practices for exceptions and error handling](errors-and-exception-handling-modern-cpp.md).
202
202
203
-
## std::atomic
203
+
## `std::atomic`
204
204
205
-
Use the C++ Standard Library [std::atomic](../standard-library/atomic-structure.md) struct and related types for inter-thread communication mechanisms.
205
+
Use the C++ Standard Library [`std::atomic`](../standard-library/atomic-structure.md) struct and related types for inter-thread communication mechanisms.
206
206
207
-
## std::variant (C++17)
207
+
## `std::variant` (C++17)
208
208
209
-
Unions are commonly used in C-style programming to conserve memory by enabling members of different types to occupy the same memory location. However, unions aren't type-safe and are prone to programming errors. C++17 introduces the [std::variant](../standard-library/variant-class.md) class as a more robust and safe alternative to unions. The [std::visit](../standard-library/variant-functions.md#visit) function can be used to access the members of a `variant` type in a type-safe manner.
209
+
Unions are commonly used in C-style programming to conserve memory by enabling members of different types to occupy the same memory location. However, unions aren't type-safe and are prone to programming errors. C++17 introduces the [`std::variant`](../standard-library/variant-class.md) class as a more robust and safe alternative to unions. The [`std::visit`](../standard-library/variant-functions.md#visit) function can be used to access the members of a `variant` type in a type-safe manner.
0 commit comments