N4527 14.6 [temp.res]/p8
If a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a constru
Here's an example:
extern const int b;
template
void f(int);
template
void f(long);
template
void g() {
f<0, b>(0);
}
// #1
extern const int b = 0;
int main(){
g();
}
// #2
A hypothetical instantiation at #1 will call void f<0, b>(long)
, because b
isn't a constant expression at that point, so the (int)
overload SFINAEs away. An instantiation at #2 (which is a point of instantiation of g
) will call void f<0, 0>(int)
, because by then b
is a constant expression, the (int)
overload is viable and wins overload resolution.
Clang and GCC will in fact call different fs with this code.