Two *template-id*s refer to the same
class, function, or variable if

- their corresponding type
*template-argument*s are the same type and - their corresponding non-type
*template-argument*s of pointer-to-member type refer to the same class member or are both the null member pointer value and - their corresponding non-type
*template-argument*s of reference type refer to the same object or function and - their remaining corresponding non-type
*template-argument*s have the same type and value after conversion to the type of the*template-parameter*, where they are considered to have the same value if they compare equal with operator<=>, and - their corresponding template
*template-argument*s refer to the same template.

[ Example

: *end example*

]template<class E, int size> class buffer { /* ... */ }; buffer<char,2*512> x; buffer<char,1024> y;

declares
x
and
y
to be of the same type, and

template<class T, void(*err_fct)()> class list { /* ... */ }; list<int,&error_handler1> x1; list<int,&error_handler2> x2; list<int,&error_handler2> x3; list<char,&error_handler2> x4;

template<class T> struct X { }; template<class> struct Y { }; template<class T> using Z = Y<T>; X<Y<int> > y; X<Z<int> > z;—

Two such *decltype-specifier*s
refer to the same type only if their *expression*s are
equivalent ([temp.over.link]).