Now there is an error. Why does the first case work but the second case fails? Furthermore, what is the point of making the template parameter "class X*"? How do you even instantiate such a template?
How do you even instantiate such a template? y<nullptr>();
It's a non-type template parameter.
If you had declared a class T prior class T;
Then you could have written template <T*> void y() {}
The class here is just a disambiguator, it's only required in cases where non-type hiding is involved:
1 2 3 4 5 6 7 8 9
class X {};
int main()
{
X a; // declares a variable of type X named a
class X b; // declares a variable of type X named b
class X X; // declares a variable of type X named X
// X c; // wrong: the identifier X now refers to the variable X
class X d; // ok - "class X" unambigously refers to the type X
}
I still don't quite understand why typename can't be used interchangeably for the template parameter in that example, because it normally can be. It's because of the pointer syntax, but I still don't understand how that's wrong.
Because it is not a type template parameter.
These are:
1 2 3
template<class X> void y() {} // X is replaced with typename
template<typename X> void y() {} // X is replaced with typename
template<typename X = std::vector<double> > void y() {}
Non-type template parameter
1 2 3 4 5
template<int X> void y() {} // 'int' is typename, X is name of value
template<int* X> void y() {} // X is name of value
template<class T* X> void y() {} // 'class T' is typename, X is name of value
template<class T*> void y() {} // 'class T' is typename, unnamed value
template<class T* X = nullptr> void y() {} // with default value