Why can a dependent name be considered as complete even if the actual type is not defined until the very end

  • A+

Consider this example:

template <class T> void Yeap(T);  int main() {     Yeap(0);     return 0; }  template <class T> void YeapImpl();  struct X;  template <class T> void Yeap(T) {     YeapImpl<X>(); // pass X to another template }  template <class T> void YeapImpl() {     T().foo(); }  struct X {     void foo() {} }; 

Note that struct X is not defined until the very end. I used to believe that all odr-used names must be complete at the point of the instantiation. But here, how can the compiler treat it as a complete type prior to its definition?

I have checked the binding rules and lookup rules of dependent name and function template instantiation in cppreference, but none of them can explain what is happening here.


I believe this program is ill-formed, no diagnostic required.

[temp.point]/8 reads, editing out the irrelevant parts:

A specialization for a function template [...] may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation. [...] If two different points of instantiation give a template specialization different meanings according to the one-definition rule, the program is ill-formed, no diagnostic required.

YeapImpl<X> has two points of instantiation: where it is called on the commented line in the question and at the end of the translation unit. In the first point of instantiation, X is incomplete which would make the body of the function ill-formed. In the second point of instantiation, X is complete which makes the body well-formed.

Those two specializations have [very] different meanings.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: