a(n) = a(n-1), a(0) = 1で定義される簡単な数列を模した算術メタ関数を作ろうとした.今回,static constな定数(value)を内部に持たずに,あくまでメタ関数としてのみの機能(type)を提供するメタ関数を作ることにこだわってみた.なので,入力・出力はboost::mpl::int_を想定.要するに「型->型」のみにこだわっている.
// 漸化式a(n) = a(n-1)を表現するメタ関数
template<class T>
struct a
{
typedef
typename a<
typename boost::mpl::minus<
T,
boost::mpl::int_<1>
>::type
>::type
type
;
};
// 再帰停止条件a(0) = 1
template<>
struct a<boost::mpl::int_<0> >
{
typedef boost::mpl::int_<1> type;
};色々試行錯誤した結果,再帰停止条件が厳しすぎる(boost::mpl::int_<0>の特殊化にドンピシャで一致しないといけない)のかと思って,SFINAEで若干緩い停止条件を書いてみた.そしたらうまく動いた.
// a(n) = a(n-1)
template<class T, class = void>
struct a
{
typedef
typename a<
typename boost::mpl::minus<
T,
boost::mpl::int_<1>
>::type
>::type
type
;
};
// a(0) = 1
template<class T>
struct a<
T,
typename boost::enable_if<typename boost::mpl::equal_to<T, boost::mpl::int_<0> >::type>::type
>
{
typedef boost::mpl::int_<1> type;
};
int main()
{
std::cout << a<boost::mpl::int_<10> >::type::value << std::endl; // a(10),つまり1
}