82

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

smallB
  • 16,662
  • 33
  • 107
  • 151

1 Answers1

77

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.

wohlstad
  • 12,661
  • 10
  • 26
  • 39
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 55
    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. – Steve Jessop Oct 14 '11 at 12:49
  • 14
    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: http://stackoverflow.com/questions/6273176/what-exactly-is-broken-with-microsoft-visual-cs-two-phase-template-instantia – Steve Jessop Oct 14 '11 at 12:56
  • @SteveJessop: That sounds more like it -- the key is the "lookup" part of the two-phase lookup. Thanks! – Kerrek SB Oct 14 '11 at 13:04
  • 3
    Historical remark: I used a compiler that had a counting braces phase and a compiling phase, IOW given `template 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. – curiousguy Oct 14 '11 at 13:54
  • 2
    For the curious, this is an excerpt from _C++ Templates: The Complete Guide_. – legends2k Aug 20 '14 at 13:58
  • 3
    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. – Richard Corden May 07 '15 at 18:23