//
// Y to be used as X argument
//
template<typename T>
class Y
{
};
//
// X template
//
template<typename T>
struct X
{
static void f();
};
//
// attempts to specialize X< Y<T> >::f
//
#define MODE 1
#if MODE == 1
template<>
void X< Y<int> >::f();
#elif MODE == 2
template<typename T>
void X< Y<T> >::f();
#elif MODE == 3
template<typename T>
template<>
void X< Y<T> >::f();
#elif MODE == 4
template<>
template<typename T>
void X< Y<T> >::f();
#endif
//
// specialization test
//
int main()
{
X< Y<int> >::f();
return 0;
}