fork download
  1. #include <iostream>
  2. #include <typeinfo>
  3. #include <memory>
  4. #include <cxxabi.h>
  5. #include <tuple>
  6. #include <type_traits>
  7.  
  8. std::string demangle(std::type_info const& type)
  9. {
  10. static int sta = 0;
  11. return {abi::__cxa_demangle(type.name(), 0, 0, &sta)};
  12. }
  13.  
  14. // class/struct template
  15. template<typename...Args>
  16. struct Foo
  17. {
  18. Foo(Args...args)
  19. {
  20. std::cout << demangle(typeid(Foo<Args...>)) << std::endl;
  21. }
  22. };
  23.  
  24. // function template
  25. template<typename...Args>
  26. void f(Args...args)
  27. {
  28. std::cout << sizeof...(Args) << std::endl;
  29. }
  30.  
  31. template<typename...Args>
  32. struct Bar
  33. {
  34. using tuple = std::tuple<Args...>;
  35. using add_const = std::tuple<typename std::add_const<Args>::type...>;
  36.  
  37. Bar()
  38. {
  39. std::cout << "tuple : " << demangle(typeid(tuple)) << std::endl;
  40. std::cout << "add_const : " << demangle(typeid(add_const)) << std::endl;
  41. }
  42. };
  43.  
  44. // pass as arguments
  45. void target()
  46. {
  47. std::cout << "no arguments" << std::endl;
  48. }
  49. void target(int, char const*)
  50. {
  51. std::cout << "2 arguments" << std::endl;
  52. }
  53.  
  54. template<typename...Args>
  55. void call(Args...args)
  56. {
  57. target(args...);
  58. }
  59.  
  60.  
  61. // recursive call
  62. template<typename...Args>
  63. struct Baz;
  64.  
  65. template<typename T, typename...Args>
  66. struct Baz<T, Args...>
  67. {
  68. void operator()(T head, Args...tail) const
  69. {
  70. std::cout << head << " ";
  71. Baz<Args...>{}(tail...);
  72. }
  73. };
  74. template<>
  75. struct Baz<>
  76. {
  77. void operator()() const
  78. {
  79. std::cout << std::endl;
  80. }
  81. };
  82. template<typename...Args>
  83. void baz(Args...args)
  84. {
  85. Baz<Args...>{}(args...);
  86. }
  87.  
  88. // integral
  89. template<int...Args>
  90. struct Sum;
  91.  
  92. template<int N, int...Args>
  93. struct Sum<N, Args...>
  94. {
  95. operator int() const
  96. {
  97. return N + Sum<Args...>{};
  98. }
  99. };
  100. template<>
  101. struct Sum<>
  102. {
  103. operator int() const { return 0; }
  104. };
  105.  
  106. // N2555: Extending variadic Template Template Parameters
  107. template<typename...Args>
  108. struct eval;
  109. template<template<typename...> class T, typename... U>
  110. struct eval<T<U...> >
  111. {};
  112. template<typename...> class A{};
  113. template<typename T> class B{};
  114. template<typename T1, typename T2> class C{};
  115. template<typename T1, typename T2, typename...> class D{};
  116.  
  117. int main(int, char*[])
  118. {
  119. // class template
  120. Foo<> x{};
  121. Foo<int> y{0};
  122. Foo<char, int, double> z{ '1', 2, 3.14 };
  123.  
  124. // function template
  125. f();
  126. f(0);
  127. f('1', 2, 3.14);
  128.  
  129. // pack operator
  130. Bar<> a{};
  131. Bar<int> b{};
  132. Bar<char, int, double> c{};
  133.  
  134. // pass as argument
  135. call();
  136. // call(0); // error
  137. call(0, "test");
  138. // call(0, 1); // error
  139.  
  140. // recursive call
  141. baz();
  142. baz(0);
  143. baz('1', 2, 3.14);
  144.  
  145. // integral parameter
  146. std::cout << demangle(typeid(Sum<1,2,3,4,5>)) << " = "
  147. << Sum<1,2,3,4,5>{} << std::endl;
  148.  
  149. // Variadic Template Template Parameters
  150. eval<A<>> e1{};
  151. eval<B<int>> e2{};
  152. eval<C<int, int>> e3{};
  153. eval<D<int, int>> e4{};
  154.  
  155. return 0;
  156. }
Success #stdin #stdout 0s 3036KB
stdin
Standard input is empty
stdout
Foo<>
Foo<int>
Foo<char, int, double>
0
1
3
tuple     : std::tuple<>
add_const : std::tuple<>
tuple     : std::tuple<int>
add_const : std::tuple<int const>
tuple     : std::tuple<char, int, double>
add_const : std::tuple<char const, int const, double const>
no arguments
2 arguments

0 
1 2 3.14 
Sum<1, 2, 3, 4, 5> = 15