例えばsumの場合、以下のように書ける。
転載元:http://yohshiy.blog.fc2.com/blog-entry-300.html
// 末端 isum inline int isum() { return 0; } // 再帰呼び出し isum template<typename First, typename... Rest> int isum(const First& first, const Rest&... rest) { return first + isum(rest...); }
+や*の場合は交換法則が成り立つ。つまり、
(a+(b+(c+d))) == (((a+b)+c)+d)
だ。しかし、例えば/の場合、交換法則が成り立たない
(a/(b/(c/d))) != (((a/b)/c)/d)
ではどうすればいいか。
// 再起の最後 template<typename First, typename Second> inline auto div(const First& first, const Second& second) { return first / second; } // 連続で割り算を行う関数 template<typename First, typename Second, typename... Rest> inline auto div(const First& first, const Second& second, const Rest& ... rest) { return div( div(first , second) , rest...); }
#include <iostream>
////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // 再起の最後 template<typename First, typename Second> inline auto div(const First& first, const Second& second) { return first / second; } // 連続で割り算を行う関数 template<typename First, typename Second, typename... Rest> inline auto div(const First& first, const Second& second, const Rest& ... rest) { return div(div(first, second), rest...); }
////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // 後ろから計算する場合 // 再起の最後 inline auto backDIV() { return 1.0; } // 連続で割り算を行う関数 template<typename First, typename... Rest> inline auto backDIV(const First& first, const Rest& ... rest) { return first / backDIV(rest...) ; }
////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int main() { std::cout << "普通計算:"; double k1 = 5.0 / 8.0 / 2.0; std::cout << k1; std::cout << std::endl; std::cout << "再帰(前方):"; double k2 = div(5.0, 8.0, 2.0); std::cout << k2; std::cout << std::endl; std::cout << "再帰(後方):"; double k3 = backDIV(5.0, 8.0, 2.0); std::cout << k3; int i; std::cin >> i; }
普通計算:0.3125 再帰(前方):0.3125 再帰(後方):1.25