C++ provides a convenient STL container, tuple
.
This is an example of using tuple
.
auto tuple1 = tuple<int, string, float> (5, "qwe", 0.4f);
auto tuple2 = make_tuple(1, 4, "qqq");
cout<<get<0>(tuple1)<<get<1>(tuple2)<<endl;
Here, get<N, T>(T& t)
is a special function template that makes you access to a tuple.
Using a variadic templates, implement a function that cout
s all elements in any tuple which has only cout
-able types.
First of all, you'll need a special helper class.
template <int...> struct Ints { /* nothing */ }
Implement class templates AtoB
, which has typedef mytype = ...
that defines Ints
instantiated with integers ranged A to B.
In other words,
typeid(AtoB<3, 8>::mytype) == typeid(Ints<3,4,5,6,7,8>)
This must hold.
Use compile-time recursion. Define a base-case specialization.
Implement the following three function templates.
template <typename T>
void print(tuple<T> a); // base case
template <typename T, typename... Args>
void print(tuple<T, Args...> a);
template<int ...S, typename... Args>
void temp(Ints<S...> not_used, const tuple<Args...>& t);
Here temp
is a helper function that retrieves S...
of some instantiated Ints
in print
.
You should call temp
from print
, and temp
should call the recursive N-1 case of print
.
print(make_tuple(5, "qwe", 3.0f));
>> 5 qwe 3.0
Parameter pack expansion can be used being enclosed with another expression. For example,
vector<int> a = {S...};
vector<int> b = {abs(S)...};
vector<float> c = {sqrt(abs(S))...};
Consider using that only in the list initialization and the function arguments passing.