fork download
  1. #include <type_traits>
  2. #include <iostream>
  3.  
  4. namespace named {
  5. struct param {};
  6.  
  7. template<class wantparam, class wanttype, class curparamname, class curparamtype, class...Rest,
  8. class allowed=typename std::enable_if<!std::is_same<wantparam,typename std::decay<curparamname>::type>::value>::type
  9. >
  10. wanttype get(curparamname, curparamtype&&, Rest&&...rest)
  11. {
  12. static_assert(std::is_base_of<param,typename std::decay<curparamname>::type>::value,"value passed to named parameter list without a name");
  13. static_assert(!std::is_base_of<param,typename std::decay<curparamtype>::type>::value,"name passed to named parameter list without a value");
  14. return get<wantparam,wanttype>(rest...);
  15. }
  16.  
  17. template<class wantparam, class wanttype, class curparamtype, class...Rest>
  18. wanttype get(wantparam, curparamtype&& value, Rest&&...)
  19. {
  20. static_assert(std::is_base_of<param,typename std::decay<wantparam>::type>::value,"value passed to named parameter list without a name");
  21. static_assert(!std::is_base_of<param,typename std::decay<curparamtype>::type>::value,"name passed to named parameter list without a value");
  22. return std::forward<curparamtype>(value);
  23. }
  24.  
  25. template<class wantparam, class wanttype, class curparamtype>
  26. wanttype get(curparamtype)
  27. {
  28. static_assert(std::is_base_of<param,typename std::decay<curparamtype>::type>::value,"value passed to named parameter list without a name");
  29. static_assert(!std::is_base_of<param,typename std::decay<curparamtype>::type>::value,"name passed to named parameter list without a value");
  30. }
  31.  
  32. template<class wantparam, class wanttype>
  33. wanttype get()
  34. {static_assert(sizeof(wantparam)==0,"missing required named parameter");}
  35.  
  36.  
  37. //add parameter names here. Make sure they all have unique types and inherit from param.
  38. static struct a_type : public param{} a;
  39. static struct b_type : public param{} b;
  40. static struct c_type : public param{} c;
  41. }
  42.  
  43. void my_func(int a, int b = 0, int c = 0){
  44. std::cout << a << ' ' << b << ' ' << c << '\n';
  45. }
  46.  
  47. template<class curparamname, class...Rest,
  48. class allowed=typename std::enable_if<std::is_base_of<named::param,typename std::decay<curparamname>::type>::value>::type
  49. >
  50. void my_func(curparamname p, Rest...rest) {
  51. return my_func(
  52. named::get<named::a_type,int>(p, rest...),
  53. named::get<named::b_type,int>(p, rest..., named::b, 0),
  54. named::get<named::c_type,int>(p, rest..., named::c, 0)
  55. );
  56. }
  57.  
  58. int main() {
  59. my_func(3);
  60. my_func(3, 4);
  61. my_func(3, 4, 5);
  62. my_func(named::c, 6, named::a, 7);
  63. //my_func(named::b, 8); //error C2338: missing required named parameter
  64. my_func(named::c, 9, named::b, 10, named::a, 11);
  65. //my_func(named::c, 12, 13, named::a, 14); //error C2338: value passed to named parameter list without a name
  66. //my_func(named::c, named::a, 15); //error C2338: named passed to named parameter list without a value
  67. return 0;
  68. }
Success #stdin #stdout 0s 3344KB
stdin
Standard input is empty
stdout
3 0 0
3 4 0
3 4 5
7 0 6
11 10 9