It seems to me that templates might not be the right way for the desired functions. I would first overload only the output operator. There are several ways to do this. Instead of the function as before, a class VectorPrinter can be created that contains a printVector functionality. The call would then be possible as follows:
abilites.push_back(Darkvision);
abilites.push_back(LowLightVision);
std::cout << "abilites:\n" << VectorPrinter(abilites) << "\n";
The VectorPrinter class contains t_strvector as a member variable and overloads the output operator << to output the contents of the vector. The desired syntax with cout can then be used by creating an object of the VectorPrinter class.
For example, the class could look like this:
typedef std::vector<std::string> t_strvector;
class VectorPrinter {
public:
VectorPrinter(const t_strvector& vectorName) : vectorName(vectorName) {}
friend std::ostream& operator<<(std::ostream& os, const VectorPrinter& vp)
{
for (size_t i = 0; i < vp.vectorName.size(); i++) {
os << vp.vectorName[i] << "\n";
}
return os;
}
private:
const t_strvector& vectorName;
};
The class can of course be written as a template to use different vector types. Here's one way to do that:
template <typename T>
class VectorPrinter {
public:
VectorPrinter(const std::vector<T>& vectorName) : vectorName(vectorName) {}
};