First commit
[cpp_sandbox.git] / Sandbox / VariadicTemplates.cpp
1 #include "VariadicTemplates.h"
2
3 #include <iostream>
4 #include <vector>
5 using namespace std;
6
7 // Introduction to C++ Variadic Templates: https://kevinushey.github.io/blog/2016/01/27/introduction-to-c++-variadic-templates/
8 // Using Variadic Templates cleanly: https://florianjw.de/en/variadic_templates.html
9 // Variadic templates in C++ : https://eli.thegreenplace.net/2014/variadic-templates-in-c/
10
11 namespace VariadicTemplates
12 {
13 template <typename ... Ts> // Template parameter pack: multiple types (0 type can be given).
14 void ignore(Ts ... ts)
15 {
16 }
17
18 template <typename T>
19 double sum(T t)
20 {
21 return t;
22 }
23 template <typename T, typename ... Ts>
24 double sum(T t, Ts ... ts)
25 {
26 return t + sum(ts...);
27 }
28
29 template <typename T>
30 T square(T t)
31 {
32 return t * t;
33 }
34 template <typename T>
35 double power_sum(T t)
36 {
37 return t;
38 }
39 template <typename T, typename ... Ts>
40 double power_sum(T t, Ts ... ts)
41 {
42 return t + power_sum(square(ts)...);
43 }
44
45 /////
46
47 struct S
48 {
49 S(int a, double b)
50 : a(a), b(b)
51 {
52 cout << "Ctor" << endl;
53 }
54
55 S(const S& other)
56 : a(other.a), b(other.b)
57 {
58 cout << "Copy ctor" << endl;
59 }
60
61 // This move ctor isn't necessary because it does the same thing as the copy ctor.
62 S(S&& other) noexcept
63 : a(other.a), b(other.b)
64 {
65 cout << "Move ctor" << endl;
66 }
67
68 const int a;
69 const double b;
70 };
71
72 ostream& operator<<(ostream& os, const S& s)
73 {
74 os << "{ a = " << s.a << ", b = " << s.b << "}";
75 return os;
76 }
77
78 /////
79
80 template<typename ... Ts>
81 void ignore_return_values(Ts&&...) {}
82
83 template<typename ... Ts>
84 void increment_all(Ts& ... values)
85 {
86 ignore_return_values((++values)...);
87 }
88 }
89
90 void VariadicTemplates::tests()
91 {
92 ignore(1, 2.0, true); // Types can be different.
93
94 cout << sum(1, 2, 3, 4) << endl;
95 cout << power_sum(1, 2, 3, 4) << endl;
96
97 /////
98
99 vector<S> v;
100 // 'emplace_back' use variadic template.
101 v.emplace_back(1, 1.5);
102 v.emplace_back(2, 1.6);
103 v.emplace_back(3, 1.7);
104
105 for (const auto& i : v)
106 cout << "element: " << i << endl;
107
108 /////
109
110 int i = 3;
111 double d = 4.5;
112 increment_all(i, d);
113 cout << i << ", " << d << endl;
114 }