Skip to content

Commit dcd787d

Browse files
author
Michael Blome
committed
more new 15.3 features and updates to conformance topic
1 parent d737691 commit dcd787d

7 files changed

+171
-32
lines changed

docs/cpp-conformance-improvements-2017.md

Lines changed: 45 additions & 18 deletions
Large diffs are not rendered by default.

docs/cpp/compound-statements-blocks.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ if( Amount > 100 )
5656
Alert();
5757
}
5858
else
59+
{
5960
Balance -= Amount;
61+
}
6062
```
6163

6264
> [!NOTE]

docs/cpp/examples-of-lambda-expressions.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,15 +282,26 @@ int main()
282282

283283
### Example
284284
You can use lambda expressions in the body of a function. The lambda expression can access any function or data member that the enclosing function can access. You can explicitly or implicitly capture the `this` pointer to provide access to functions and data members of the enclosing class.
285+
**Visual Studio 2017 version 15.3 and later**: Capture `this` by value (`[*this]`) when the lambda will be used in asynchronous or parallel operations where the code might execute after the original object goes out of scope.
285286

286287
You can use the `this` pointer explicitly in a function, as shown here:
287288

288289
```cpp
290+
291+
// capture "this" by reference
289292
void ApplyScale(const vector<int>& v) const
290293
{
291294
for_each(v.begin(), v.end(),
292295
[this](int n) { cout << n * _scale << endl; });
293296
}
297+
298+
// capture "this" by value (Visual Studio 2017 version 15.3 and later)
299+
void ApplyScale2(const vector<int>& v) const
300+
{
301+
for_each(v.begin(), v.end(),
302+
[*this](int n) { cout << n * _scale << endl; });
303+
}
304+
294305
```
295306
296307
You can also capture the `this` pointer implicitly:

docs/cpp/if-else-statement-cpp.md

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ else // optional
4747
...
4848
}
4949
50+
// Visual Studio 2017 version 15.3 and later:
5051
if ( initialization; expression )
5152
{
5253
   statement1;
@@ -57,6 +58,18 @@ else // optional
5758
   statement2;
5859
...
5960
}
61+
62+
// Visual Studio 2017 version 15.3 and later:
63+
if constexpr (expression)
64+
{
65+
statement1;
66+
...
67+
}
68+
else // optional
69+
{
70+
   statement2;
71+
...
72+
}
6073
```
6174
## Example
6275
```
@@ -105,7 +118,7 @@ int main()
105118
}
106119
```
107120
## if statement with an initializer
108-
**Visual Studio 2017 version 15.3 and later:** An **if** statement may also contain an initialization expression, as shown in the following example:
121+
**Visual Studio 2017 version 15.3 and later**: An **if** statement may also contain an expression that declares and initializes a named variable. Use this form of the if-statement when the variable is only needed within the scope of the if-block.
109122

110123
```cpp
111124
## Example
@@ -143,18 +156,38 @@ int main()
143156
shared_flag = false;
144157
}
145158

159+
146160
string s{ "if" };
147-
if (auto keywords = { "if", "for", "while" }; any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
161+
if (auto keywords = { "if", "for", "while" }; any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
148162
{
149163
cout << "Error! Token must not be a keyword\n";
150164
}
151165

152166
}
153167
```
154-
## Remarks
168+
155169
In all forms of the **if** statement, *expression*, which can have any value except a structure, is evaluated, including all side effects. Control passes from the **if** statement to the next statement in the program unless one of the *statement*s contains a [break](../cpp/break-statement-cpp.md), [continue](../cpp/continue-statement-cpp.md), or [goto](../cpp/goto-statement-cpp.md).
156170

157171
The **else** clause of an `if...else` statement is associated with the closest previous **if** statement in the same scope that does not have a corresponding **else** statement.
172+
173+
## constexpr if statements
174+
**Visual Studio 2017 version 15.3 and later**: In function templates, you can use a **constexpr if** statement to make compile-time branching decisions without having to resort to multiple function overloads. For example, you can write a single function that handles parameter unpacking (no zero-parameter overload is needed):
175+
176+
```cpp
177+
template <class T, class... Rest>
178+
void f(T&& t, Rest&&... r)
179+
{
180+
// handle t
181+
do_something(t);
182+
183+
constexpr if (sizeof...(r))
184+
{
185+
// handle r
186+
f(r...);
187+
}
188+
}
189+
```
190+
158191
159192
160193
## See Also

docs/cpp/lambda-expressions-in-cpp.md

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "Lambda Expressions in C++ | Microsoft Docs"
33
ms.custom: ""
4-
ms.date: "11/04/2016"
4+
ms.date: "07/19/2017"
55
ms.reviewer: ""
66
ms.suite: ""
77
ms.technology:
@@ -35,8 +35,13 @@ translation.priority.ht:
3535
- "zh-tw"
3636
---
3737
# Lambda Expressions in C++
38-
In C++11 and later, a lambda expression—often called a *lambda*—is a convenient way of defining an anonymous function object right at the location where it is invoked or passed as an argument to a function. Typically lambdas are used to encapsulate a few lines of code that are passed to algorithms or asynchronous methods. This article defines what lambdas are, compares them to other programming techniques, describes their advantages, and provides a basic example.
39-
38+
In C++11 and later, a lambda expression—often called a *lambda*—is a convenient way of defining an anonymous function object (a *closure*) right at the location where it is invoked or passed as an argument to a function. Typically lambdas are used to encapsulate a few lines of code that are passed to algorithms or asynchronous methods. This article defines what lambdas are, compares them to other programming techniques, describes their advantages, and provides a basic example.
39+
40+
## Related Topics
41+
- [Lambda expressions vs. function objects](lambda-expression-syntax.md)
42+
- [Working with lambda expressions](examples-of-lambda-expressions.md)
43+
- [constexpr lambda expressions](lambda-expressions-constexpr.md)
44+
4045
## Parts of a Lambda Expression
4146
The ISO C++ Standard shows a simple lambda that is passed as the third argument to the `std::sort()` function:
4247

@@ -95,10 +100,11 @@ void abssort(float* x, unsigned n) {
95100
struct S { void f(int i); };
96101

97102
void S::f(int i) {
98-
[&, i]{}; // OK
99-
[&, &i]{}; // ERROR: i preceded by & when & is the default
100-
[=, this]{}; // ERROR: this when = is the default
101-
[i, i]{}; // ERROR: i repeated
103+
[&, i]{}; // OK
104+
[&, &i]{}; // ERROR: i preceded by & when & is the default
105+
[=, this]{}; // ERROR: this when = is the default
106+
[=, *this]{ }; // OK: captures this by value. See below.
107+
[i, i]{}; // ERROR: i repeated
102108
}
103109
```
104110
@@ -112,7 +118,10 @@ void f(Args... args) {
112118
}
113119
```
114120

115-
To use lambda expressions in the body of a class method, pass the `this` pointer to the capture clause to provide access to the methods and data members of the enclosing class. For an example that shows how to use lambda expressions with class methods, see "Example: Using a Lambda Expression in a Method" in [Examples of Lambda Expressions](../cpp/examples-of-lambda-expressions.md).
121+
To use lambda expressions in the body of a class method, pass the `this` pointer to the capture clause to provide access to the methods and data members of the enclosing class.
122+
**Visual Studio 2017 version 15.3 and later**: The `this` pointer may be captured by value by specifying `*this` in the capture clause. Capture by value means that the entire *closure*, which is the anonymous function object that encapulates the lambda expression, is copied to every call site where the lambda is invoked. Capture by value is useful when the lambda will execute in parallel or asynchronous operations, especially on certain hardware architectures such as NUMA.
123+
124+
For an example that shows how to use lambda expressions with class methods, see "Example: Using a Lambda Expression in a Method" in [Examples of Lambda Expressions](../cpp/examples-of-lambda-expressions.md).
116125

117126
When you use the capture clause, we recommend that you keep these points in mind, particularly when you use lambdas with multithreading:
118127

@@ -325,6 +334,43 @@ vector v after 2nd call to fillVector(): 10 11 12 13 14 15 16 17 18
325334
```
326335

327336
For more information, see [generate_n](../standard-library/algorithm-functions.md#generate_n).
337+
338+
## constexpr lambda expressions
339+
**Visual Studio 2017 version 15.3 and later**: A lambda expression may be declared as `constexpr` or used in a contant expression when the initialization of each data member that it captures or introduces is allowed within a constant expression.
340+
341+
```cpp
342+
int y = 32;
343+
auto answer = [y]() constexpr
344+
{
345+
int x = 10;
346+
return y + x;
347+
};
348+
349+
constexpr int Increment(int n)
350+
{
351+
return [n] { return n + 1; }();
352+
}
353+
354+
```
355+
A lambda is implicitly `constexpr` if its result satisfies the requirements of a `constexpr` function:
356+
```cpp
357+
auto answer = [](int n)
358+
{
359+
return 32 + n;
360+
};
361+
362+
constexpr int response = answer(10);
363+
```
364+
If a lambda is implicitly or explicitly `constexpr`, conversion to a function pointer produces a `constexpr` function:
365+
366+
```cpp
367+
auto Increment = [](int n)
368+
{
369+
return n + 1;
370+
};
371+
372+
constexpr int(*inc)(int) = Increment;
373+
```
328374
329375
## Microsoft-Specific
330376
Lambdas are not supported in the following common language runtime (CLR) managed entities: `ref class`, `ref struct`, `value class`, or `value struct`.

docs/preprocessor/hash-if-hash-elif-hash-else-and-hash-endif-directives-c-cpp.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ f1_keywords:
1313
- "#endif"
1414
- "#if"
1515
- "#elif"
16-
- "Defined"
16+
- "defined"
17+
- "__has_include"
1718
dev_langs:
1819
- "C++"
1920
helpviewer_keywords:
@@ -111,7 +112,8 @@ The `#if` directive, with the `#elif`, `#else`, and `#endif` directives, control
111112
- The translator can translate character constants to a set of code values different from the set for the target environment. To determine the properties of the target environment, check values of macros from LIMITS.H in an application built for the target environment.
112113

113114
- The expression must not perform any environmental inquiries and must remain insulated from implementation details on the target computer.
114-
115+
116+
## defined
115117
The preprocessor operator **defined** can be used in special constant expressions, as shown by the following syntax:
116118

117119
defined( `identifier` )
@@ -190,6 +192,24 @@ class Example
190192
```
191193

192194
The preceding code checks to see if the symbolic constant `EXAMPLE_H` is defined. If so, the file has already been included and need not be reprocessed. If not, the constant `EXAMPLE_H` is defined to mark EXAMPLE.H as already processed.
195+
196+
## __has_include
197+
**Visual Studio 2017 version 15.3 and later**: Determines whether a library header is available for inclusion:
198+
199+
```cpp
200+
#ifdef __has_include
201+
# if __has_include(<filesystem>)
202+
# include <filesystem>
203+
# define have_filesystem 1
204+
# elif __has_include(<experimental/filesystem>)
205+
# include <experimental/filesystem>
206+
# define have_filesystem 1
207+
# define experimental_filesystem
208+
# else
209+
# define have_filesystem 0
210+
# endif
211+
#endif
212+
```
193213

194214
## See Also
195215
[Preprocessor Directives](../preprocessor/preprocessor-directives.md)

docs/preprocessor/predefined-macros.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ The Visual C++ compiler predefines certain preprocessor macros, depending on the
187187
```
188188

189189
## Standard predefined macros
190-
The compiler supports these predefined macros specified by the ISO C99 and ISO C++14 standards.
190+
The compiler supports these predefined macros specified by the ISO C99 and ISO C++17 standards.
191191

192192
- **__cplusplus** Defined as an integer literal value when the translation unit is compiled as C++. Otherwise, undefined.
193193

0 commit comments

Comments
 (0)