#include <iostream>
#include <functional>
// Manual function definitions.
std::function<double(double)> plus2(double a){
return[a](double b){return a + b; };
}
auto plus3(double a) {
return [a](double b){ return plus2(a + b); };
}
// -----
// Automatic function definitions.
template<int N>
auto plus(double a);
template<int N>
auto plus(double a) {
return [a](double b){ return plus<N - 1>(a + b); };
}
template<>
auto plus<1>(double a) {
return a;
}
// -----
int main() {
std::cout << "Manual:\n"
<< plus2(1)(2) << ' '
<< plus3(1)(2)(3) << '\n'
<< "\nTemplate:\n"
<< plus<2>(1)(2) << ' '
<< plus<3>(1)(2)(3) << ' '
<< plus<4>(1)(2)(3)(4) << ' '
<< plus<5>(1)(2)(3)(4)(5) << '\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCi8vIE1hbnVhbCBmdW5jdGlvbiBkZWZpbml0aW9ucy4KICAgIHN0ZDo6ZnVuY3Rpb248ZG91YmxlKGRvdWJsZSk+IHBsdXMyKGRvdWJsZSBhKXsKICAgICAgICByZXR1cm5bYV0oZG91YmxlIGIpe3JldHVybiBhICsgYjsgfTsKICAgIH0KICAgIAogICAgYXV0byBwbHVzMyhkb3VibGUgYSkgewogICAgICAgIHJldHVybiBbYV0oZG91YmxlIGIpeyByZXR1cm4gcGx1czIoYSArIGIpOyB9OwogICAgfQoKLy8gLS0tLS0KCi8vIEF1dG9tYXRpYyBmdW5jdGlvbiBkZWZpbml0aW9ucy4KICAgIHRlbXBsYXRlPGludCBOPgogICAgYXV0byBwbHVzKGRvdWJsZSBhKTsKICAgIAogICAgdGVtcGxhdGU8aW50IE4+CiAgICBhdXRvIHBsdXMoZG91YmxlIGEpIHsKICAgICAgICByZXR1cm4gW2FdKGRvdWJsZSBiKXsgcmV0dXJuIHBsdXM8TiAtIDE+KGEgKyBiKTsgfTsKICAgIH0KICAgIAogICAgdGVtcGxhdGU8PgogICAgYXV0byBwbHVzPDE+KGRvdWJsZSBhKSB7CiAgICAgICAgcmV0dXJuIGE7CiAgICB9CiAgICAKLy8gLS0tLS0KCmludCBtYWluKCkgewoJc3RkOjpjb3V0IDw8ICJNYW51YWw6XG4iCgkJCSAgPDwgcGx1czIoMSkoMikgICAgPDwgJyAnCgkJCSAgPDwgcGx1czMoMSkoMikoMykgPDwgJ1xuJwoJCQkgIDw8ICJcblRlbXBsYXRlOlxuIgoJCQkgIDw8IHBsdXM8Mj4oMSkoMikgICAgICAgICAgPDwgJyAnCgkJCSAgPDwgcGx1czwzPigxKSgyKSgzKSAgICAgICA8PCAnICcKCQkJICA8PCBwbHVzPDQ+KDEpKDIpKDMpKDQpICAgIDw8ICcgJwoJCQkgIDw8IHBsdXM8NT4oMSkoMikoMykoNCkoNSkgPDwgJ1xuJzsKfQ==