fork download
  1. #include <memory>
  2.  
  3. template<class...Ts>struct types:std::integral_constant<unsigned,sizeof...(Ts)>
  4. {typedef types type;};
  5. template<class T,class types>struct index_of;
  6. template<class T,class T0, class...Ts>struct index_of<T,types<T0,Ts...>>:
  7. std::integral_constant<unsigned,index_of<T,types<Ts...>>::value+1>
  8. {};
  9. template<class T,class...Ts>struct index_of<T,types<T,Ts...>>:
  10. std::integral_constant<unsigned,0>
  11. {};
  12. template<unsigned,class types>struct type_at;
  13. template<unsigned N, class T,class...Ts>struct type_at<N,types<T,Ts...>>:
  14. type_at<N-1,types<Ts...>> {};
  15. template<class T,class...Ts>struct type_at<0,types<T,Ts...>>{
  16. typedef T type;
  17. };
  18. template<unsigned N,class types>
  19. using type_at_t=typename type_at<N,types>::type;
  20.  
  21. template<template<class>class Target,unsigned N,class types>
  22. struct nth_apply;
  23. template<template<class>class Target,unsigned N,class...Ts>
  24. struct nth_apply<Target,N,types<Ts...>>{
  25. typedef Target<type_at_t<N,types> type;
  26. };
  27. template<template<class>class Target,unsigned N,class...Ts>
  28. struct nth_apply<Target,N,types<Ts...>>{
  29. typedef Target<type_at_t<N,types> type;
  30. };
  31. template<template<class>class Target,unsigned N,class types>
  32. using nth_apply_t=typename nth_apply<Target,N,types>::type;
  33.  
  34. template<class T>struct shared_maker{
  35. template<class...Args>
  36. std::shared_ptr<T> operator()(Args&&...args)const{
  37. return std::make_shared<T>(std::forward<Args>(args)...);
  38. }
  39. template<class R, class Args>
  40. operator R(*)(Args...)() const{
  41. return [](Args... args)->R{
  42. return make_shared{}(std::forward<Args>(args)...);
  43. };
  44. }
  45. };
  46. struct A; struct B; // etc
  47. typedef types<A,B> Alphabet_Types;
  48. struct Alphabet {};
  49. template<class D>
  50. struct Letter:Alphabet{
  51. static const unsigned index = index_of<D, Alphabet_Types>::value;
  52. };
  53. typedef std::shared_ptr<Alphabet> spAlphabet;
  54. std::array<spAlphabet(*)(), Alphabet_Types::value> factories();
  55.  
  56. //the goal is simple: create the function factories that returns an array of Alphabet makers. When implementing a letter, do:
  57.  
  58. struct A:Letter<A>{};
  59.  
  60. //ie, use Letter<> as a CRTP base instead of Alphabet.
  61.  
  62. //The only thing left is factories.
  63.  
  64. template<unsigned...>struct indexes{typedef indexes type;};
  65. template<unsigned Max, unsigned... Is> struct make_indexes:make_indexea<Max-1,Max-1,Is...>{};
  66. template<unsigned...Is>struct make_indexes<0,Is...>:indexes<Is...>{};
  67.  
  68. std::array<spAlphabet(*)(), Alphabet_Types::value,unsigned...Is> factories(indexes<Is...>){
  69. return {nth_apply_t<shared_maker,Is,Alphabet_Types>{}...};
  70. }
  71. std::array<spAlphabet(*)(), Alphabet_Types::value> factories(){
  72. return factories(make_indexes<Alphabet_Types::value>{});
  73. }
  74.  
  75. int main() {
  76.  
  77. }
Compilation error #stdin compilation error #stdout 0s 3296KB
stdin
Standard input is empty
compilation info
prog.cpp:25:35: error: type/value mismatch at argument 2 in template parameter list for ‘template<unsigned int N, class types> using type_at_t = typename type_at::type’
   typedef Target<type_at_t<N,types> type;
                                   ^
prog.cpp:25:35: error:   expected a type, got ‘types’
prog.cpp:25:37: error: template argument 1 is invalid
   typedef Target<type_at_t<N,types> type;
                                     ^
prog.cpp:25:11: warning: ‘typedef’ was ignored in this declaration [enabled by default]
   typedef Target<type_at_t<N,types> type;
           ^
prog.cpp:28:8: error: redefinition of ‘struct nth_apply<Target, N, types<Ts ...> >’
 struct nth_apply<Target,N,types<Ts...>>{
        ^
prog.cpp:24:8: error: previous definition of ‘struct nth_apply<Target, N, types<Ts ...> >’
 struct nth_apply<Target,N,types<Ts...>>{
        ^
prog.cpp:40:14: error: expected identifier before ‘*’ token
   operator R(*)(Args...)() const{
              ^
prog.cpp:40:28: error: ‘<invalid operator>’ declared as function returning a function
   operator R(*)(Args...)() const{
                            ^
prog.cpp:65:72: error: expected template-name before ‘<’ token
 template<unsigned Max, unsigned... Is> struct make_indexes:make_indexea<Max-1,Max-1,Is...>{};
                                                                        ^
prog.cpp:65:72: error: expected ‘{’ before ‘<’ token
prog.cpp:65:72: error: expected unqualified-id before ‘<’ token
prog.cpp:68:59: error: expansion pattern ‘unsigned int’ contains no argument packs
 std::array<spAlphabet(*)(), Alphabet_Types::value,unsigned...Is> factories(indexes<Is...>){
                                                           ^
prog.cpp:68:64: error: wrong number of template arguments (3, should be 2)
 std::array<spAlphabet(*)(), Alphabet_Types::value,unsigned...Is> factories(indexes<Is...>){
                                                                ^
In file included from /usr/include/c++/4.8/tuple:39:0,
                 from /usr/include/c++/4.8/functional:55,
                 from /usr/include/c++/4.8/memory:79,
                 from prog.cpp:1:
/usr/include/c++/4.8/array:81:12: error: provided for ‘template<class _Tp, unsigned int _Nm> struct std::array’
     struct array
            ^
prog.cpp:68:84: error: ‘Is’ was not declared in this scope
 std::array<spAlphabet(*)(), Alphabet_Types::value,unsigned...Is> factories(indexes<Is...>){
                                                                                    ^
prog.cpp:68:86: error: expected parameter pack before ‘...’
 std::array<spAlphabet(*)(), Alphabet_Types::value,unsigned...Is> factories(indexes<Is...>){
                                                                                      ^
prog.cpp:68:89: error: template argument 1 is invalid
 std::array<spAlphabet(*)(), Alphabet_Types::value,unsigned...Is> factories(indexes<Is...>){
                                                                                         ^
prog.cpp: In function ‘int factories(int)’:
prog.cpp:69:36: error: ‘Is’ was not declared in this scope
   return {nth_apply_t<shared_maker,Is,Alphabet_Types>{}...};
                                    ^
prog.cpp:69:53: error: template argument 2 is invalid
   return {nth_apply_t<shared_maker,Is,Alphabet_Types>{}...};
                                                     ^
prog.cpp:69:59: error: cannot convert ‘<brace-enclosed initializer list>’ to ‘int’ in return
   return {nth_apply_t<shared_maker,Is,Alphabet_Types>{}...};
                                                           ^
prog.cpp: In function ‘std::array<std::shared_ptr<Alphabet> (*)(), 2u> factories()’:
prog.cpp:72:56: error: invalid use of incomplete type ‘struct make_indexes<2u>’
   return factories(make_indexes<Alphabet_Types::value>{});
                                                        ^
prog.cpp:65:47: error: declaration of ‘struct make_indexes<2u>’
 template<unsigned Max, unsigned... Is> struct make_indexes:make_indexea<Max-1,Max-1,Is...>{};
                                               ^
prog.cpp: In function ‘int factories(int)’:
prog.cpp:70:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
prog.cpp: In function ‘std::array<std::shared_ptr<Alphabet> (*)(), 2u> factories()’:
prog.cpp:73:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
stdout
Standard output is empty