Here is such a simple function template that returns a double value. But in the parameters I can only write numbers? ( int , double ...) But only numbers? Is it possible to do something like this so that we can also write a string to the parameters and allow something like stringstring to be output or is it from the realm of fantasy? The compiler takes the word data as numbers of different types, or else can it be perceived as a string data type, for example?

 template< class TYPE > void PrintTwice(TYPE data) { cout << "Double meaning: " << data * 2 << endl; } 
  • 3
    Try instead of data * 2 to write data + data , pass a string object to the template function and look at the output of the program :) - wololo
  • @wololo says that the binary + operator is not suitable for char data types. that means function templates have limitations ... - Maryna Said
  • 3
    Example - wololo
  • @wololo is super! out !! thank you !!! - Maryna Said
  • 2
    "means function templates have limitations" - if very briefly, in this particular case, there is not a restriction of templates, but the fact that you cannot multiply objects of type string by integers. - wololo

2 answers 2

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; } 

    If the multiplication operator is overloaded for the type being transferred, this should work, otherwise a compilation error will be caused.

    You can write a template specialization for a string:

     template<> void PrintTwice(std::string data) { std::cout << "Double meaning: " << data + data << std::endl; } 
    • 2
      And even easier - to remove the template<> and not suffer :) - overloading for functions is no worse than specialization. - Harry