I am trying to create a template for easily outputting containers, for the purpose of debugging code. I would like to be able to do
int a = 3;
pair<int,int> b = {2,3};
vector<int> c = {1,2,3,4};
map<int,int> m;
m[2] = 3;
m[3] = 4;
dbg(a,b,c,m);
OUTPUT:
[a,b,c,m] = [ 3 , (2,3) , {1,2,3,4} , {(2,3),(3,4)} ]
So far I have this:
#define dbg(x...) cout << "[" << #x << "] = [ "; _dbg(x); cout << "]"
template <typename T> void _dbg(T t)
{
cout << t << " ";
}
template<typename T, typename... Args>
void _dbg(T t, Args... args) // recursive variadic function
{
cout << t << " , ";
_dbg(args...);
}
template <typename T, typename V>
ostream& operator<<(ostream& os, const pair<T, V> p)
{
cout << "(" << p.first << "," << p.second << ")";
}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& dt)
{
cout << "{";
auto preEnd = dt.end();
preEnd--;
for (auto bgn = dt.begin(); bgn != preEnd; bgn++)
cout << *bgn << ",";
cout << *preEnd << "}";
return os;
}
template <typename T>
ostream& operator<<(ostream& os, const set<T>& dt)
{
cout << "{";
auto preEnd = dt.end();
preEnd--;
for (auto bgn = dt.begin(); bgn != preEnd; bgn++)
cout << *bgn << ",";
cout << *preEnd << "}";
return os;
}
template <typename T, typename V>
ostream& operator<<(ostream& os, const map<T, V>& dt)
{
cout << "{";
auto preEnd = dt.end();
preEnd--;
for (auto bgn = dt.begin(); bgn != preEnd; bgn++)
cout << *bgn << ",";
cout << *preEnd << "}";
return os;
}
And it works great! It's just that I don't want to define a function for every single container type, when they all would have the same body (talking about the last 3 functions). I tried something like
template<typename C, typename T>
ostream& operator<<(ostream& os, const C<T>& dt)
But I got
error: C is not a template
and I tried
template<typename C>
ostream& operator<< (ostream& os, const C& dt)
And got
error: no match for 'operator<<' (operand types are
'std::ostream {aka std::basic_ostream<char>}' and 'std::set<int>')|
So how do I just have one generic function that deals with any container (ex. one being template<typename T> vector<T>
, and the other set<T>
??)