#include <iostream>
#include <iomanip>
#include <type_traits>

template <typename T>
struct Identity
{
	typedef T result;
};

template <typename T, T v>
struct Constant
{
	typedef T type;
	static constexpr T value = v;
};

template <int N>
using Int = Constant<int, N>;

template <template <typename, typename, typename...> class function, typename arg2>
struct bind2nd
{
	template <typename arg1, typename... args>
	struct binder : function<arg1, arg2, args...>
	{};
};

template <typename left, typename right>
struct plus : Identity<Constant<decltype(left::value + right::value), left::value + right::value>>
{};

template <typename arg>
struct plus1 : bind2nd<plus, Int<1>>::template binder<arg>
{};

int main()
{
	std::cout << std::boolalpha << std::is_same<plus1<Int<100>>::result, Int<101>>::value;
}