3

As per the title, I do not understand how can the following code compile when has_type_struct<no_type> is certainly an invalid type.

template<typename T>
using my_int = int;

struct no_type {};

template<typename T>
struct has_type_struct { using type = typename T::type; };

template<typename T>
using has_type_using = typename T::type;

int main() {
   my_int<has_type_struct<no_type>> a; // why does this compile?
   //my_int<has_type_using<no_type>>(); // this rightfully does not compile
   return 0;
}
cpplearner
  • 13,776
  • 2
  • 47
  • 72
blue
  • 2,683
  • 19
  • 29

1 Answers1

2

The program is valid because has_type_struct<no_type> is not instantiated.

[temp.inst]/1:

Unless a class template specialization has been explicitly instantiated or explicitly specialized, the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program.

The use of my_int<has_type_struct<no_type>> does not require has_type_struct<no_type> to be complete, therefore the latter is not instantiated and the validity of the dependent name in its definition is not checked.

cpplearner
  • 13,776
  • 2
  • 47
  • 72
  • I think it's very surprising that the validity of the template argument is never checked in this case, but it looks like it's a direct consequence of that snippet of standardese. – blue May 18 '17 at 10:11
  • p.s. w.r.t. the standard, one might argue that in this case the "completeness of the class type" *does* affect the "semantics of the program", but oh well – blue May 18 '17 at 10:20
  • Completeness of a type means something specific, see [here](http://en.cppreference.com/w/cpp/language/type#Incomplete_type). Completeness doesn't affect semantics in your case. For another example, we can forward-declare a class template to use as a template argument: `template class fwd; my_int> b;` The type of `b` wouldn't change if we provide a definition for `fwd`. – Oktalist May 18 '17 at 12:11