Skip to content

Commit 85f1102

Browse files
author
Colin Robertson
committed
Yet another example for /Zc:twoPhase-
1 parent bf74729 commit 85f1102

File tree

1 file changed

+49
-1
lines changed

1 file changed

+49
-1
lines changed

docs/build/reference/zc-twophase.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,55 @@ int main()
6868
}
6969
```
7070

71-
When compiled under **/Zc:twoPhase-**, this program prints "The call resolves to int". In conformance mode, this program prints "The call resolves to void*", because the second overload of `func` is not visible when the compiler encounters the template.
71+
When compiled under **/Zc:twoPhase-**, this program prints "The call resolves to int". In conformance mode under **/permissive-**, this program prints "The call resolves to void*", because the second overload of `func` is not visible when the compiler encounters the template.
72+
73+
*Dependent names*, names that depend on a template parameter, have lookup behavior that is also different under **/Zc:twoPhase-**. In conformance mode, dependent names are not bound at the point of the template’s definition. Instead, these names are looked up when the template is instantiated. For function calls with a dependent function name, the name is bound to the set of functions that are visible at the point of the call in the template’s definition, as above. Additional overloads from argument-dependent lookup are added at both the point of the template definition and the point of where the template is instantiated. The two phases of two-phase lookup are the lookup for non-dependent names at the time of template definition, and lookup for dependent names at the time of template instantiation. Under **/Zc:twoPhase-**, the compiler does not do argument-dependent lookup separately from ordinary, unqualified lookup (that is, it doesn't do two-phase lookup), so the results of overload resolution may be different.
74+
75+
Here's another example:
76+
77+
```cpp
78+
// zctwophase1.cpp
79+
// Compile by using
80+
// cl /EHsc /W4 /permissive- zctwophase1.cpp
81+
// cl /EHsc /W4 /permissive- /Zc:twoPhase- zctwophase1.cpp
82+
83+
#include <cstdio>
84+
85+
void func(long) { std::puts("func(long)"); }
86+
87+
template <typename T> void tfunc(T t) {
88+
func(t);
89+
}
90+
91+
void func(int) { std::puts("func(int)"); }
92+
93+
namespace NS {
94+
struct S {};
95+
void func(S) { std::puts("NS::func(NS::S)"); }
96+
}
97+
98+
int main() {
99+
tfunc(1729);
100+
NS::S s;
101+
tfunc(s);
102+
}
103+
```
104+
105+
When compiled without **/Zc:twoPhase-**, this prints
106+
107+
```Output
108+
func(long)
109+
NS::func(NS::S)
110+
```
111+
112+
When compiled with **/Zc:twoPhase-**, this prints
113+
114+
```Output
115+
func(int)
116+
NS::func(NS::S)
117+
```
118+
119+
In conformance mode under **/permissive-**, the call `tfunc(1729)` resolves to the `void func(long)` overload, not `void func(int)` overload as under **/Zc:twoPhase-**, because the unqualified `func(int)` is declared after the definition of the template and not found through argument-dependent lookup. But `void func(S)` does participate in argument-dependent lookup, so it is added to the overload set for the call `tfunc(s)` even though it is declared after the template function.
72120

73121
### Update your code for two-phase conformance
74122

0 commit comments

Comments
 (0)