Here is two-phase name lookup for template from iso-standard:
When looking for the declaration of a name used in a template definition, the usual lookup rules (6.4.1, 6.4.2) are used for non-dependent names.
The lookup of names dependent on the template parameters is postponed until the actual template argument is known
Sample codes:
#include <iostream>
void WithoutTemplate(int) {std::cout << "NonTemplate: int\n";}
template<typename T>
void WithTemplate(T) {std::cout << "no match\n";}
template<>
void WithTemplate(int) {std::cout <<"Template: int\n";}
template<typename T>
void test(T)
{
WithTemplate(1.1);
WithoutTemplate(1.1);
}
void WithoutTemplate(double) {std::cout << "nontemplate: double\n";}
template<>
void WithTemplate(double) {std::cout << "template: double\n";}
int main()
{
test(1.1);
}
output:
template: double NonTemplate: int
There are two functions: WithTemplate
and WithoutTemplate
. The parameter 1.1
is non-dependent(though it is prvalue, which has no name? I assume it still obey non-dependent name's rules)
- name lookup of
WithoutTemplate
meets 2-phase lookup, because when callingWithoutTemplate(1.1)
,void WithoutTemplate(double)
is not visible. So the outputNonTemplate: int
is easy to understand. - However, the case which invokes full specialization function quite confuses me. its behaviour is opposite to the standard's rules(2-phase lookup). I thought it should output
template: int
So, is there other name lookup rules for specialization? Or something else I misunderstand?
Here is what I have read: