高階 template

ふつうにできるのを知ってショックでした。
以前、それらしく書いてみたらコンパイルエラーだったので、
できないと思い込んでいた。

// パラメータとして型を渡す template class
template< typename T > class T0 {};

// パラメータとして1階テンプレートクラスを渡す template class
template< template<typename> class T > class T1 {};

// パラメータとして2階テンプレートクラスを渡す template class
template< template<template<typename> class> class T > class T2 {};

// パラメータとしてテンプレートと型を受け取り、テンプレート適用をする
template<template<typename> class TMPL, typename T> class ApplyTmpl {
public:
  typedef TMPL<T> type;
  type constructor() { return type(); }
  type* newInstance() { return new type(); }
};

// パラメータとして値を渡す関数
int f0(int x) { return 0; }

// パラメータとして1階関数を渡す関数
int f1(int (*x)(int)) { return 0; }

// パラメータとして2階関数を渡す関数
int f2(int (*x)(int (*)(int))) { return 0; }

// パラメータとして関数と値を受け取り、関数適用をする
int apply_func(int (*x)(int), int y) {
  return x(y);
}