Skip to content

Commit a659a4c

Browse files
authored
Merge pull request #4548 from corob-msft/docs/corob/function-template
Address 4178 plus template function -> function template
2 parents b3231d5 + f6bf876 commit a659a4c

38 files changed

+602
-605
lines changed

docs/atl/reference/ccomenum-class.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ The code shown below provides a reusable function for creating and initializing
7676

7777
[!code-cpp[NVC_ATL_COM#32](../../atl/codesnippet/cpp/ccomenum-class_1.h)]
7878

79-
This template function can be used to implement the `_NewEnum` property of a collection interface as shown below:
79+
This function template can be used to implement the `_NewEnum` property of a collection interface as shown below:
8080

8181
[!code-cpp[NVC_ATL_COM#33](../../atl/codesnippet/cpp/ccomenum-class_2.h)]
8282

docs/atl/reference/ccomenumonstl-class.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ The code shown below provides a generic function to handle the creation and init
8585

8686
[!code-cpp[NVC_ATL_COM#34](../../atl/codesnippet/cpp/ccomenumonstl-class_1.h)]
8787

88-
This template function can be used to implement the `_NewEnum` property of a collection interface as shown below:
88+
This function template can be used to implement the `_NewEnum` property of a collection interface as shown below:
8989

9090
[!code-cpp[NVC_ATL_COM#35](../../atl/codesnippet/cpp/ccomenumonstl-class_2.h)]
9191

docs/build/reference/zc-twophase.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
---
22
title: "/Zc:twoPhase- (disable two-phase name lookup)"
33
description: "Explains how /Zc:twoPhase- disables two-phase name lookup when /permissive- is specified."
4-
ms.date: "12/03/2019"
4+
ms.date: 09/27/2022
55
f1_keywords: ["twoPhase", "/Zc:twoPhase"]
66
helpviewer_keywords: ["twoPhase", "disable two-phase name lookup", "/Zc:twoPhase"]
77
---
8-
# /Zc:twoPhase- (disable two-phase name lookup)
8+
# `/Zc:twoPhase-` (disable two-phase name lookup)
99

10-
The **/Zc:twoPhase-** option, under **/permissive-**, tells the compiler to use the original, non-conforming Microsoft C++ compiler behavior to parse and instantiate class templates and function templates.
10+
The **`/Zc:twoPhase-`** option, under **`/permissive-`**, tells the compiler to use the original, non-conforming Microsoft C++ compiler behavior to parse and instantiate class templates and function templates.
1111

1212
## Syntax
1313

14-
> **/Zc:twoPhase-**
14+
> **`/Zc:twoPhase-`**
1515
1616
## Remarks
1717

18-
Visual Studio 2017 version 15.3 and later: Under [/permissive-](permissive-standards-conformance.md), the compiler uses two-phase name lookup for template name resolution. If you also specify **/Zc:twoPhase-**, the compiler reverts to its previous non-conforming class template and function template name resolution and substitution behavior. When **/permissive-** isn't specified, the non-conforming behavior is the default.
18+
Visual Studio 2017 version 15.3 and later: Under [`/permissive-`](permissive-standards-conformance.md), the compiler uses two-phase name lookup for template name resolution. If you also specify **`/Zc:twoPhase-`**, the compiler reverts to its previous non-conforming class template and function template name resolution and substitution behavior. When **`/permissive-`** isn't specified, the non-conforming behavior is the default.
1919

20-
The Windows SDK header files in version 10.0.15063.0 (Creators Update or RS2) and earlier don't work in conformance mode. **/Zc:twoPhase-** is required to compile code for those SDK versions when you use **/permissive-**. Versions of the Windows SDK starting with version 10.0.15254.0 (Fall Creators Update or RS3) work correctly in conformance mode. They don't require the **/Zc:twoPhase-** option.
20+
The Windows SDK header files in version 10.0.15063.0 (Creators Update or RS2) and earlier don't work in conformance mode. **`/Zc:twoPhase-`** is required to compile code for those SDK versions when you use **`/permissive-`**. Versions of the Windows SDK starting with version 10.0.15254.0 (Fall Creators Update or RS3) work correctly in conformance mode. They don't require the **`/Zc:twoPhase-`** option.
2121

22-
Use **/Zc:twoPhase-** if your code requires the old behavior to compile correctly. Strongly consider updating your code to conform to the standard.
22+
Use **`/Zc:twoPhase-`** if your code requires the old behavior to compile correctly. Strongly consider updating your code to conform to the standard.
2323

24-
### Compiler behavior under /Zc:twoPhase-
24+
### Compiler behavior under `/Zc:twoPhase-`
2525

26-
By default, or in Visual Studio 2017 version 15.3 and later when you specify both **/permissive-** and **/Zc:twoPhase-**, the compiler uses this behavior:
26+
By default, or in Visual Studio 2017 version 15.3 and later when you specify both **`/permissive-`** and **`/Zc:twoPhase-`**, the compiler uses this behavior:
2727

2828
- It parses only the template declaration, the class head, and the base class list. The template body is captured as a token stream. No function bodies, initializers, default arguments, or noexcept arguments are parsed. The class template is pseudo-instantiated on a tentative type to validate that the declarations in the class template are correct. Consider this class template:
2929

@@ -33,7 +33,7 @@ By default, or in Visual Studio 2017 version 15.3 and later when you specify bot
3333
3434
The template declaration, `template <typename T>`, the class head `class Derived`, and the base-class list `public Base<T>` are parsed, but the template body is captured as a token stream.
3535
36-
- When parsing a function template, the compiler parses only the function signature. The function body is never parsed. Instead, it's captured as a token stream.
36+
- When it parses a function template, the compiler parses only the function signature. The function body is never parsed. Instead, it's captured as a token stream.
3737
3838
As a result, if the template body has syntax errors, but the template never gets instantiated, the compiler doesn't diagnose the errors.
3939
@@ -65,7 +65,7 @@ int main()
6565
}
6666
```
6767

68-
Here's the output when you use the default mode, conformance mode, and conformance mode with **/Zc:twoPhase-** compiler options:
68+
Here's the output when you use the default mode, conformance mode, and conformance mode with **`/Zc:twoPhase-`** compiler options:
6969

7070
```cmd
7171
C:\Temp>cl /EHsc /nologo /W4 zctwophase.cpp && zctwophase
@@ -81,11 +81,11 @@ zctwophase.cpp
8181
Microsoft one-phase
8282
```
8383

84-
When compiled in conformance mode under **/permissive-**, this program prints "`Standard two-phase`", because the second overload of `func` isn't visible when the compiler reaches the template. If you add **/Zc:twoPhase-**, the program prints "`Microsoft one-phase`". The output is the same as when you don't specify **/permissive-**.
84+
When compiled in conformance mode under **`/permissive-`**, this program prints "`Standard two-phase`", because the second overload of `func` isn't visible when the compiler reaches the template. If you add **`/Zc:twoPhase-`**, the program prints "`Microsoft one-phase`". The output is the same as when you don't specify **`/permissive-`**.
8585

86-
*Dependent names* are names that depend on a template parameter. These names have lookup behavior that is also different under **/Zc:twoPhase-**. In conformance mode, dependent names aren't bound at the point of the template's definition. Instead, the compiler looks them up when it instantiates the template. For function calls with a dependent function name, the name gets bound to functions visible at the call site in the template definition. Additional overloads from argument-dependent lookup are added, both at the point of the template definition, and at the point of template instantiation.
86+
*Dependent names* are names that depend on a template parameter. These names have lookup behavior that is also different under **`/Zc:twoPhase-`**. In conformance mode, dependent names aren't bound at the point of the template's definition. Instead, the compiler looks them up when it instantiates the template. For function calls with a dependent function name, the name gets bound to functions visible at the call site in the template definition. Other overloads from argument-dependent lookup are added, both at the point of the template definition, and at the point of template instantiation.
8787

88-
Two-phase lookup consists of two parts: The lookup for non-dependent names during template definition, and the lookup for dependent names during template instantiation. Under **/Zc:twoPhase-**, the compiler doesn't do argument-dependent lookup separately from unqualified lookup. That is, it doesn't do two-phase lookup, so the results of overload resolution may be different.
88+
Two-phase lookup consists of two parts: The lookup for non-dependent names during template definition, and the lookup for dependent names during template instantiation. Under **`/Zc:twoPhase-`**, the compiler doesn't do argument-dependent lookup separately from unqualified lookup. That is, it doesn't do two-phase lookup, so the results of overload resolution may be different.
8989

9090
Here's another example:
9191

@@ -118,28 +118,28 @@ int main() {
118118
}
119119
```
120120
121-
When compiled without **/permissive-**, this code prints:
121+
When compiled without **`/permissive-`**, this code prints:
122122
123123
```Output
124124
func(int)
125125
NS::func(NS::S)
126126
```
127127

128-
When compiled with **/permissive-**, but without **/Zc:twoPhase-**, this code prints:
128+
When compiled with **`/permissive-`**, but without **`/Zc:twoPhase-`**, this code prints:
129129

130130
```Output
131131
func(long)
132132
NS::func(NS::S)
133133
```
134134

135-
When compiled with both **/permissive-** and **/Zc:twoPhase-**, this code prints:
135+
When compiled with both **`/permissive-`** and **`/Zc:twoPhase-`**, this code prints:
136136

137137
```Output
138138
func(int)
139139
NS::func(NS::S)
140140
```
141141

142-
In conformance mode under **/permissive-**, the call `tfunc(1729)` resolves to the `void func(long)` overload. It doesn't resolve to the `void func(int)` overload, as under **/Zc:twoPhase-**. That's because the unqualified `func(int)` is declared after the definition of the template, and it isn't found through argument-dependent lookup. But `void func(S)` does participate in argument-dependent lookup, so it's added to the overload set for the call `tfunc(s)`, even though it's declared after the template function.
142+
In conformance mode under **`/permissive-`**, the call `tfunc(1729)` resolves to the `void func(long)` overload. It doesn't resolve to the `void func(int)` overload, as under **`/Zc:twoPhase-`**. The reason is, the unqualified `func(int)` is declared after the definition of the template, and it isn't found through argument-dependent lookup. But `void func(S)` does participate in argument-dependent lookup, so it's added to the overload set for the call `tfunc(s)`, even though it's declared after the function template.
143143

144144
### Update your code for two-phase conformance
145145

@@ -151,7 +151,7 @@ A conforming compiler parses `Foo` as a variable in the scope of `T`, meaning th
151151

152152
`T::template Foo<a || b>(c);`
153153

154-
In versions Visual Studio 2017 version 15.3 and later, when **/permissive-** and **/Zc:twoPhase-** are specified, the compiler allows this code without the **`template`** keyword. It interprets the code as a call to a function template with an argument of `a || b`, because it only parses templates in a limited fashion. The code above isn't parsed at all in the first phase. During the second phase, there's enough context to tell that `T::Foo` is a template rather than a variable, so the compiler doesn't enforce use of the keyword.
154+
In versions Visual Studio 2017 version 15.3 and later, when **`/permissive-`** and **`/Zc:twoPhase-`** are specified, the compiler allows this code without the **`template`** keyword. It interprets the code as a call to a function template with an argument of `a || b`, because it only parses templates in a limited fashion. The code above isn't parsed at all in the first phase. During the second phase, there's enough context to tell that `T::Foo` is a template rather than a variable, so the compiler doesn't enforce use of the keyword.
155155

156156
This behavior can also be seen by eliminating the keyword **`typename`** before names in function template bodies, initializers, default arguments, and noexcept arguments. For example:
157157

@@ -163,7 +163,7 @@ typename T::TYPE func(typename T::TYPE*)
163163
}
164164
```
165165
166-
If you don't use the keyword **`typename`** in the function body, this code compiles under **/permissive- /Zc:twoPhase-**, but not under **/permissive-** alone. The **`typename`** keyword is required to indicate that the `TYPE` is dependent. Because the body isn't parsed under **/Zc:twoPhase-**, the compiler does't require the keyword. In **/permissive-** conformance mode, code without the **`typename`** keyword generates errors. To migrate your code to conformance in Visual Studio 2017 version 15.3 and beyond, insert the **`typename`** keyword where it's missing.
166+
If you don't use the keyword **`typename`** in the function body, this code compiles under **`/permissive- /Zc:twoPhase-`**, but not under **`/permissive-`** alone. The **`typename`** keyword is required to indicate that the `TYPE` is dependent. Because the body isn't parsed under **`/Zc:twoPhase-`**, the compiler does't require the keyword. In **`/permissive-`** conformance mode, code without the **`typename`** keyword generates errors. To migrate your code to conformance in Visual Studio 2017 version 15.3 and beyond, insert the **`typename`** keyword where it's missing.
167167
168168
Similarly, consider this code sample:
169169
@@ -175,18 +175,18 @@ typename T::template X<T>::TYPE func(typename T::TYPE)
175175
}
176176
```
177177

178-
Under **/permissive- /Zc:twoPhase-** and in older compilers, the compiler only requires the **`template`** keyword on line 2. In conformance mode, the compiler now also requires the **`template`** keyword on line 4 to indicate that `T::X<T>` is a template. Look for code that is missing this keyword, and supply it to make your code conform to the standard.
178+
Under **`/permissive- /Zc:twoPhase-`** and in older compilers, the compiler only requires the **`template`** keyword on line 2. In conformance mode, the compiler now also requires the **`template`** keyword on line 4 to indicate that `T::X<T>` is a template. Look for code that is missing this keyword, and supply it to make your code conform to the standard.
179179

180-
For more information about conformance issues, see [C++ conformance improvements in Visual Studio](../../overview/cpp-conformance-improvements.md) and [Nonstandard Behavior](../../cpp/nonstandard-behavior.md).
180+
For more information about conformance issues, see [C++ conformance improvements in Visual Studio](../../overview/cpp-conformance-improvements.md) and [Nonstandard behavior](../../cpp/nonstandard-behavior.md).
181181

182182
### To set this compiler option in the Visual Studio development environment
183183

184184
1. Open the project's **Property Pages** dialog box. For details, see [Set C++ compiler and build properties in Visual Studio](../working-with-project-properties.md).
185185

186186
1. Select the **Configuration Properties** > **C/C++** > **Command Line** property page.
187187

188-
1. Modify the **Additional Options** property to include **/Zc:twoPhase-** and then choose **OK**.
188+
1. Modify the **Additional Options** property to include *`/Zc:twoPhase-`* and then choose **OK**.
189189

190190
## See also
191191

192-
[/Zc (Conformance)](zc-conformance.md)
192+
[`/Zc` (Conformance)](zc-conformance.md)

0 commit comments

Comments
 (0)