In your template function, you can pass not only numbers, but absolutely everything, for which the expression data * 2 has some meaning and returns a result that can be output via << .
For example, if we overload the binary * for std::string like this
std::string operator *(std::string lhs, unsigned rhs) { std::string str; for (; rhs > 0; --rhs) str += lhs; return str; }
then your template will do exactly what you want, that is, output a double string
PrintTwice(std::string("test"));
This is the whole essence of the templates: they implement the concept of duck typing ("duck typing"). They don't care deeply what types you use in them and whether these types are somehow related to each other. All they need is that after substituting these types into the template code, this code will be formally correct.
From this point of view, this question echoes your own (now remote) question of why overloading the operator << for a custom type of Date , if you can do without it.
In fact, by overloading the output operator << for your Date type, you thereby made it compatible with the existing tools of the standard library. For example, just like we can "in one line", using the standard algorithm std::copy , output the whole array of objects std::string
std::string mama[] = ( "Mama", "myla", "ramu" }; std::copy(std::begin(mama), std::end(mama), std::ostream_iterator<std::string>(std::cout, "\n"));
we will be able to output and an array of your Date objects
Date date[] = { ... }; std::copy(std::begin(date), std::end(date), std::ostream_iterator<Date>(std::cout, "\n"));
but only if the << operator is defined for your Date .
In this case, by defining the * operator for std::string , we made std::string compatible with your PrintTwice function.
However, this approach — with redefining the * operator for std::string — should be used only if such a redefinition is a natural and logical extension of the functionality of std::string . In this case, the answer to this question is ambiguous (no, rather than yes). I gave it only as an example.
And if you consider this behavior of the * operator for std::string unnatural, then a more appropriate way of adapting the PrintTwice function to working with std::string would be an explicit specialization (as in the @Boris answer) or, better, the usual function overload
void PrintTwice(const std::string &data) { std::cout << "Double meaning: " << data << data << std::endl; }
data * 2to writedata + data, pass astringobject to the template function and look at the output of the program :) - wololostringby integers. - wololo