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 }