#include <iostream>
#include <string>

// Reusable

template<int i, class T>
struct optional_type{
	enum{ pos = i};
	typedef T value_type;

	T val_;

	const T& value()const{return val_;}
	optional_type(T rv):val_(rv){}

	optional_type():val_(){}


};

template<int i, class T>
struct required_type{
	enum{ pos = i};
	typedef T value_type;

	T val_;

	const T& value()const{return val_;}
	required_type(T rv):val_(rv){}

private:
	required_type();


};

template<int i, class T,class F>
struct defaulted_type{
	enum{ pos = i};
	typedef T value_type;
	F f;
	T val_;

	const T& value()const{return val_;}
	defaulted_type(T rv):val_(rv){}

	defaulted_type():val_(f()){}


};




template<class... Args>
struct arg_holder:public Args...{

	template<class T>
	const typename T::value_type& get()const{
		const T* ret = this;
		return ret ->value();
	}

	template<class... T>
	arg_holder(T... t):T(t)...{};


};

// What you need to implement for a function
struct user_arg_default{
	std::string operator()(){return "Somebody";};
};

typedef optional_type<0,int> value;
typedef defaulted_type<1,std::string,user_arg_default> user;
typedef required_type<2,int> required;


void greet(const arg_holder<value,user,required>& a){
	std::cout << "Hello " << a.get<user>() << " the value is " << a.get<value>()
		<< " Required " << a.get<required>() <<  std::endl;
}

int main(){
	greet({required(11)});
	greet({required(11),value(10)});
	greet({user("John"),required(11),value(10)});
	greet({required(11),user("John")});

	// the required parameter is required, if you uncomment below, you will get an error
	//greet({});
	//greet({value(10)});
	//greet({user("John"),value(10)});
	//greet({user("John")});
}