[C++]テンプレートテンプレートパラメータの“テンプレート引数の数”を取得することはできるのだろうか。

 例えば次のようなクラステンプレートX、Yがあったとする。

template <class>
struct X {};

template <class, class>
struct Y {};

Xはテンプレート引数が1個、Yはテンプレート引数が2個である。

 このX、Yを次のようなクラステンプレートに与えてみる。このXorYは、与えられたXやYのテンプレート引数の数を知ることはできるのだろうか。

template <template <class...A> class T>
struct XorY
{
    //static constexpr size_t NumOfTArgs = sizeof...(A);これは不可能。
};
//XorY<X>::NumOfTArgs == 1;
//XorY<Y>::NumOfTArgs == 2;
//であってほしい。

 テンプレート引数の数はXなら1個、Yなら2個であるが、XorYのテンプレートテンプレートパラメータは可変長であるため、そのままでは分からない。

 色々と悩んだが、次のようにconstexprな関数のオーバーロードで解決する方法しか思いつかなかった。

template <template <class> class T>
constexpr size_t NumOfTArgs() { return 1; }
template <template <class, class> class T>
constexpr size_t NumOfTArgs() { return 2; }

template <template <class...> class T>
struct XorY
{
    static constexpr size_t NumOfTArgs = NumOfTArgs<T>();
};

次のような部分特殊化ができないかとも思ったが、どうやら不可能なようだ。

template <template <class...> class T>
struct NumOfTArgs;
template <template <class> class T>
struct NumOfTArgs<T> { static constexpr size_t value = 1; };
template <template <class, class> class T>
struct NumOfTArgs<T> { static constexpr size_t value = 2; };
//プライマリテンプレートの仮引数Tと2個の部分特殊化の引数Tとが一致してしまっているためコンパイルエラー。

 テンプレートテンプレートパラメータは不可欠な機能であるが、ちょっと不便な所も多い印象だ。非型テンプレート引数にautoを使えないC++14以前だと融通が効かないのでしばしば苦労するし、上のXorYに非テンプレートなクラスを渡せないのも面倒だ。通常の可変長引数テンプレートは引数0個が許されるのに、テンプレートテンプレートパラメータでは許されないという厄介さ。何とかならないものだろうか。