Skip to content

Commit aef1492

Browse files
author
mikeblome
committed
Merge branch 'mb-153' of github.com:MicrosoftDocs/cpp-docs-pr into mb-153
local merge
2 parents 05085ba + 7617d6e commit aef1492

9 files changed

+350
-88
lines changed

docs/cpp-conformance-improvements-2017.md

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

docs/cpp/TOC.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@
231231
## [Lambda Expressions in C++](lambda-expressions-in-cpp.md)
232232
### [Lambda Expression Syntax](lambda-expression-syntax.md)
233233
### [Examples of Lambda Expressions](examples-of-lambda-expressions.md)
234+
### [constexpr Lambda Expressions](lambda-expressions-constexpr.md)
234235
## [Arrays (C++)](arrays-cpp.md)
235236
### [Using Arrays (C++)](using-arrays-cpp.md)
236237
### [Initializing Arrays](initializing-arrays.md)

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: 152 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "if-else Statement (C++) | Microsoft Docs"
33
ms.custom: ""
4-
ms.date: "11/04/2016"
4+
ms.date: "07/17/2017"
55
ms.reviewer: ""
66
ms.suite: ""
77
ms.technology:
@@ -24,79 +24,172 @@ caps.latest.revision: 13
2424
author: "mikeblome"
2525
ms.author: "mblome"
2626
manager: "ghogen"
27-
translation.priority.ht:
28-
- "cs-cz"
29-
- "de-de"
30-
- "es-es"
31-
- "fr-fr"
32-
- "it-it"
33-
- "ja-jp"
34-
- "ko-kr"
35-
- "pl-pl"
36-
- "pt-br"
37-
- "ru-ru"
38-
- "tr-tr"
39-
- "zh-cn"
40-
- "zh-tw"
4127
---
4228
# if-else Statement (C++)
43-
Controls conditional branching.
29+
Controls conditional branching. Statements in the *if-block* are executed only if the *if-expression* evaluates to a non-zero value (or `true`). If the value of *expression* is nonzero, *statement1* and any other statements in the block are executed and the else-block, if present, is skipped. If the value of *expression* is zero, then the if-block is skipped and the else-block, if present, is executed. Expressions that evaluate to non-zero are
30+
- `true`
31+
- a non-null pointer,
32+
- any non-zero arithmetic value, or
33+
- a class type that defines an unambiguous conversion to an arithmetic, boolean or pointer type. (For information about conversions, see [Standard Conversions](../cpp/standard-conversions.md).)
4434

4535
## Syntax
4636

4737
```
38+
4839
if ( expression )
49-
   statement1
50-
[else
51-
   statement2]
40+
{
41+
   statement1;
42+
...
43+
}
44+
else // optional
45+
{
46+
   statement2;
47+
...
48+
}
49+
50+
// Visual Studio 2017 version 15.3 and later:
51+
if ( initialization; expression )
52+
{
53+
   statement1;
54+
...
55+
}
56+
else // optional
57+
{
58+
   statement2;
59+
...
60+
}
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+
}
5273
```
53-
54-
## Remarks
55-
If the value of *expression* is nonzero, *statement1* is executed. If the optional **else** is present, *statement2* is executed if the value of *expression* is zero. *expression* must be of arithmetic or pointer type, or it must be of a class type that defines an unambiguous conversion to an arithmetic or pointer type. (For information about conversions, see [Standard Conversions](../cpp/standard-conversions.md).)
56-
57-
In both 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).
58-
59-
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.
60-
61-
For this sample to be unambiguous about `if...else` pairing, uncomment the braces.
62-
6374
## Example
64-
6575
```
6676
// if_else_statement.cpp
67-
#include <stdio.h>
68-
69-
int main()
70-
{
71-
int x = 0;
72-
if (x == 0)
73-
{
74-
printf_s("x is 0!\n");
75-
}
76-
else
77-
{
78-
printf_s("x is not 0!\n"); // this statement will not be executed
79-
}
80-
81-
x = 1;
82-
if (x == 0)
83-
{
84-
printf_s("x is 0!\n"); // this statement will not be executed
85-
}
86-
else
87-
{
88-
printf_s("x is not 0!\n");
89-
}
77+
#include <iostream>
78+
79+
using namespace std;
80+
81+
class C
82+
{
83+
public:
84+
void do_somthing(){}
85+
};
86+
void init(C){}
87+
bool is_true() { return true; }
88+
int x = 10;
89+
90+
int main()
91+
{
92+
if (is_true())
93+
{
94+
cout << "b is true!\n"; // executed
95+
}
96+
else
97+
{
98+
cout << "b is false!\n";
99+
}
100+
101+
// no else statement
102+
if (x == 10)
103+
{
104+
x = 0;
105+
}
106+
90107
91-
return 0;
92-
}
108+
C* c;
109+
init(c);
110+
if (c)
111+
{
112+
c->do_something();
113+
}
114+
else
115+
{
116+
cout << "c is null!\n";
117+
}
118+
}
93119
```
120+
## if statement with an initializer
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.
122+
123+
```cpp
124+
## Example
125+
#include <iostream>
126+
#include <mutex>
127+
#include <map>
128+
#include <string>
129+
#include <algorithm>
130+
131+
132+
using namespace std;
133+
134+
map<int, string> m;
135+
mutex mx;
136+
bool shared_flag; // guarded by mx
137+
void unsafe_operation() {}
138+
139+
int main()
140+
{
141+
142+
if (auto it = m.find(10); it != m.end())
143+
{
144+
cout << it->second;
145+
return 0;
146+
}
147+
148+
if (char buf[10]; fgets(buf, 10, stdin))
149+
{
150+
m[0] += buf;
151+
}
152+
153+
if (lock_guard<mutex> lock(mx); shared_flag)
154+
{
155+
unsafe_operation();
156+
shared_flag = false;
157+
}
158+
159+
160+
string s{ "if" };
161+
if (auto keywords = { "if", "for", "while" }; any_of(keywords.begin(), keywords.end(), [&s](const char* kw) { return s == kw; }))
162+
{
163+
cout << "Error! Token must not be a keyword\n";
164+
}
165+
166+
}
167+
```
168+
169+
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).
94170

95-
```Output
96-
x is 0!
97-
x is not 0!
98-
```
171+
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+
99191
192+
100193
## See Also
101194
[Selection Statements](../cpp/selection-statements-cpp.md)
102195
[Keywords](../cpp/keywords-cpp.md)
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
title: "constexpr Lambda Expressions in C++ | Microsoft Docs"
3+
ms.custom: ""
4+
ms.date: "07/19/2017"
5+
ms.reviewer: ""
6+
ms.suite: ""
7+
ms.technology:
8+
- "cpp-language"
9+
ms.tgt_pltfrm: ""
10+
ms.topic: "language-reference"
11+
dev_langs:
12+
- "C++"
13+
helpviewer_keywords:
14+
- "lambda expressions [C++], constexpr"
15+
ms.assetid: b56346cd-fbff-475f-aeaa-ed2010c6d6f7
16+
caps.latest.revision: 0
17+
author: "mikeblome"
18+
ms.author: "mblome"
19+
manager: "ghogen"
20+
---
21+
# constexpr Lambda Expressions in C++
22+
In 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.
23+
24+
```cpp
25+
int y = 32;
26+
auto answer = [y]() constexpr
27+
{
28+
int x = 10;
29+
return y + x;
30+
};
31+
32+
constexpr int Increment(int n)
33+
{
34+
return [n] { return n + 1; }();
35+
}
36+
37+
```
38+
A lambda is implicitly `constexpr` if its result satisfies the requirements of a `constexpr` function:
39+
```cpp
40+
auto answer = [](int n)
41+
{
42+
return 32 + n;
43+
};
44+
45+
constexpr int response = answer(10);
46+
```
47+
If a lambda is implicitly or explicitly `constexpr`, and you convert it to a function pointer, the resulting function is also `constexpr`:
48+
49+
```cpp
50+
auto Increment = [](int n)
51+
{
52+
return n + 1;
53+
};
54+
55+
constexpr int(*inc)(int) = Increment;
56+
```
57+
58+
## See Also
59+
[C++ Language Reference](../cpp/cpp-language-reference.md)
60+
[Function Objects in the C++ Standard Library](../standard-library/function-objects-in-the-stl.md)
61+
[Function Call](../cpp/function-call-cpp.md)
62+
[for_each](../standard-library/algorithm-functions.md#for_each)

0 commit comments

Comments
 (0)