Here's what the standard says about non-dependent names in a template definition:
Non-dependent names used in a template definition are found using the usual name lookup and bound at the point they are used.
[Example 1:
void g(double); void h(); template<class T> class Z { public: void f() { g(1); // calls g(double) h++; // ill-formed: cannot increment function; this could be diagnosed // either here or at the point of instantiation } }; void g(int); // not in scope at the point of the template definition, not considered for the call g(1)
— end example]
I'm confused by the comment on h++;
that says "ill-formed: ... this could be diagnosed either here or at the point of instantiation". What if an implementation chooses the latter, but there isn't an instantiation of the template? Where would this be diagnosed?
Does that mean this is actually ill-formed, no diagnostic required instead?
Ill-formed NDR is a specific case of ill-formed. In the example, the definition of class template
Z
clearly is ill-formed; whether or not a diagnostic is required depends on whether or not an instantiation ofZ
occurs anywhere in the translation unit, which the example appears agnostic about (since it admits that there may be a point of instantiation). If there is indeed an instantiation, then the implementation has freedom to issue the diagnostic either at the point of definition or at the point of instantiation. See [temp.res.general]/8.