Two phase lookup - explanation needed
Asked Answered
M

1

83

What does it mean that compiler is using two phase lookup in order to compile template class?

Mccabe answered 14/10, 2011 at 12:32 Comment(3)
@Nawaz I've heard only about two phase lookup, is there something I'm missing?Mccabe
A brief and useful article on the subject can be found at blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.htmlAztec
See also https://mcmap.net/q/244290/-why-can-39-t-i-use-variable-of-parent-class-that-is-template-class and https://mcmap.net/q/244291/-template-instantiation-details-of-gcc-and-ms-compilersRadiolarian
M
78

Templates are compiled (at least) twice:

  1. Without Instantiation the template code itself is checked for syntax.
    Eg: Any syntax errors such as ; etc.

  2. At the time of instantiation(when the exact type is known), the template code is checked again to ensure all calls are valid for that particular type.
    Eg: The template might in turn call to functions which might not be present for that particular type.

This is called as Two Phase Lookup.

Mortenson answered 14/10, 2011 at 12:39 Comment(6)
Also note that lookup for non-dependent names is done in the first phase, whereas lookup for names that depend on a template parameter is done in the second phase. The significance is that if you call sqrt(1), then sqrt needs to be declared before the template is defined. But if you call sqrt(t), where t is an instance of a type that's a template parameter, then sqrt needn't be visible until the template is instantiated. MSVC didn't used to do this correctly: still might not for all I know.Scabrous
Anyway, that's why it's called two phase lookup as opposed to just two phase compilation or something. The first phase is supposed to do more than merely check syntax, but MS had some difficulty implementing the first lookup phase, so they just did it all at instantiation: #6273676Scabrous
@SteveJessop: That sounds more like it -- the key is the "lookup" part of the two-phase lookup. Thanks!Freeman
Historical remark: I used a compiler that had a counting braces phase and a compiling phase, IOW given template <class T> class C { put really anything here & ~ - (but nothing unbalanced and no 8-bit char outside string literal) } would be accepted iff C was never instanciated! That was more than a decade ago.Actually
For the curious, this is an excerpt from C++ Templates: The Complete Guide.Advisee
In addition to @SteveJessop's comment on dependent names, it's also worth pointing out that it's "argument dependent lookup" that happens on the dependent names. This means that ::sqrt(::NS::A) will not be found as the additional lookup will take place in ::NS and not in ::. The final point is that the scope of an alias, typedef or using, won't be searched, only the scope of the alised type itself.Mcvay

© 2022 - 2024 — McMap. All rights reserved.