Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 495
felix Avatar asked Sep 18 '18 14:09

felix


1 Answers

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.

like image 135
Barry Avatar answered Sep 16 '22 12:09

Barry