Bar is an independent name (i.e. its type does not depend on T ), so the compiler must check the correctness of the code during the first phase of the name search (see note below).
Since Bar does not have a nonexistent_method() method, the compiler must issue a diagnosis.
If you change your template to:
template<typename T> void foo(T t, T bar) { t.compiler_does_not_care(); bar.nonexistent_method(); }
No independent names are involved, so an error does not occur because the template is never created (search step 2)
Notes:
- A clear description of finding two-phase names from LLVM :
1) Template definition time: at the initial analysis of the template, long before its creation, the compiler analyzes the template and looks for any "independent" names. The name is "independent" if the search results by name are independent of the template parameters and therefore will be the same from one instance of the template to another.
2) Template creation time: when an instance of the template is created, the compiler looks at any "dependent" names, now that it has the full set of template arguments to perform the search. The results of this search can (and often do!) Vary from one instance of the template to another.
- As to why the search for dependent names cannot be delayed to the second stage, see this other SO publication ; this seems to be mainly for historical reasons.
source share