Reputation: 87
I guess you have seen this particular function:
template<typename T> void print(const T& cont){
for (auto &i: cont)
std::cout << i << " ";
std::cout << std::endl;
}
It print's almost all type of containers like std::list
. Now i wanna create one that prints (as example) 3D std::vector
, look at this fantasy:
template<typename T1, typename T2> void print(const T1<T2>&);
But of course this is not how templates work. How to do that? And not less important: is any difference of doing that in c++17 and pre-c++17?
Upvotes: 2
Views: 82
Reputation: 60238
You can write the following template overloads, one that prints a 1-D range, and one that prints an N-D range by printing each nested (N-1)D range in a loop:
template<template<typename...> class Range,
// ^ ^
// Note the template template parameter
typename T>
void print(Range<T> const & cont) // #1
{
for (auto const & i : cont)
std::cout << i << " "; // print 1-D range
std::cout << std::endl;
}
template<template<typename...> class RangeOut,
template<typename...> class RangeIn,
typename T>
void print(RangeOut<RangeIn<T>> const & cont) // #2
{
for (auto const &i: cont)
print(i); // call print overload:
// calls #1 if RangeIn is 1-D range
// calls #2 otherwise
std::cout << std::endl;
}
Now you can print containers (ranges) of arbitrary dimensionality, and composed of heterogenous types, e.g:
std::vector<std::list<std::vector<int>>> vlv{{{1,2}, {3}} ,{{4,5}, {6}}};
print(vlv); // ok
Here's a demo.
Upvotes: 5