When instantiating a template, should members of its incomplete argument types be visible?

Whether typename T::Before is valid is not explicitly said by the spec. It is subject of a defect report (because the Standard can very reasonably be read to forbid it): http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287 .

Whether typename T::After is invalid can also very reasonably be read to be true by the spec, and actually it makes quite a bit of sense (and aforementioned DR still keeps it ill-formed). Because you have an instantiation of a class A<Foo>, which references another class A<Bar> during a period where a member Baz has not yet been declared, and that makes a reference back to A<Foo>::Bar. That is ill-formed in the case of non-templates aswell (try to “forget” for a moment that you are dealing with templates: surely the lookup of B<A>::After is done after the A template was completely parsed, but not after the specific instantiation of it was completely created. And it is the instantiation of it that actually will do the reference!).

struct A {
   typedef int Foo;
   typedef A::Foo Bar; // valid
   typedef A::Baz Lulz; // *not* valid
   typedef int Baz; 
};

Leave a Comment