I find myself with a situation that has Generics written all over it, but I've never (successfully) implemented them. I understand the theory, but the examples never seem even closely related to what I want to do.
In this case, I have a very basic function requirement: print all values of a table. I'm using different types of containers, mostly vectors of ints, floats or booleans. The tables are a vector of these vectors. Thus, for example, the int table would be: vector<vector<int>>, or using typedef: "intlist = vector<int>" & "intbox = vector<intlist>".
Currently, each primitive variable type I need has its own list and box container. However, this also means that basic functions that take a table as input need to be redefined for each of the primitive types. As a result, every primitive type's list and box containers have a print function associated with them, which does the exact same for every primitive type, but takes a different parameter (e.g. one for intbox, one for floatbox, etc). The actual code is the exact same, except for the datatype in the parameter.
Could anyone show me how to use generics/templates for this?
The two functions printList and printBox will work with any STL collection type (well, printBox only with collections of collections of course). If you want to use maps (you probably won't, but imagine you do) you will need another function:
EDIT: Made the pair a const pair reference in the << operator. Seriously, what was I thinking?
EDIT2: Added an extra space in the main function, to prevent compiler collapse (some compilers might read vector<list<int>> intBox; as operator>>(vector<list<, intintBox); instead of vector<list<int> > intBox; Stupid I know, but it could happen.
That you can pass a constant parameter. Printing a constant doesn't change the constant, so it should be allowed. Otherwise you could only use mutable datatypes, which is pointless.
PS: Depending on your situation, it may be more meaningful to additionally pass an ostream& to your function, so you could choose where to print, for example like this:
I'm using the direct-print version, since that's all I need for the current program. I'm wondering what the "out=cout" notation means though? (In your return-to-ostream version)
Also, why do you still add "return" to void methods? Is it just a habit, or is it proper/better coding practice?
Also, why do you still add "return" to void methods? Is it just a habit, or is it proper/better coding practice?
For consistency issues. If all the other functions have return statements, why shouldn't the void functions have one? It's technically not needed, but I personally like it better that way.
I'm wondering what the "out=cout" notation means though?
It's a default parameter. Basically, what it says is that you can provide an ostream as a third parameter, however you do not have to. If you don't, the function behaves as if you passed cout as the third parameter. Which means, you could replace the second version of those templates by the first without changing the code at all, but it would gave you the power to call the function e.g. with an ofstream as the third parameter, which would print the whole thing to a file instead.