The C++ standard requires that template instantiation be lazy; that is, the substitution of template parameters must be delayed until an instruction is hit which allocates storage space for a template instance’s object or which accesses a member of the template instance’s object. If Y didn’t have foo() and there was no allocation or member access on the by pointer in main() the compiler would not fail.