language: C++11 (gcc-4.7.2)
date: 82 days 13 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#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")});
}