#include <iostream>
#include <functional>

template <typename T>
class yoba {
public:
	yoba(const T& n, std::function<T(T)> func)
		: n(n), func(func) {}
	
	T next() {
		n = func(n);
		return n;
	}
private:
	T n;
	std::function<T(T)> func;
};


template <typename T>
struct return_type : public return_type<decltype(&T::operator())> {};

template <typename C, typename R, typename... Args>
struct return_type<R(C::*)(Args...) const> {
	using type = R;
};

template <typename Func> 
auto make_yoba(Func func) -> std::function<yoba<typename return_type<Func>::type>(typename return_type<Func>::type)> {
	using T = typename return_type<Func>::type;
	return [func] (const T& n) {
		return yoba<T>(n, func);
	};
}

auto main() -> int {
	auto yoba_int = make_yoba([] (int n) -> int {
		return n + 1;
	});
	auto yoba_double = make_yoba([] (double n) -> double {
		return n / 2;
	});
	
	auto yoba_int5 = yoba_int(5);
	
	std::cout << yoba_int5.next() << std::endl;
	std::cout << yoba_int5.next() << std::endl;
	
	auto yoba_double238 = yoba_double(2.38);
	
	std::cout << yoba_double238.next() << std::endl;
	std::cout << yoba_double238.next() << std::endl;

	return 0;
}
