3
template<>std::string Add(std::string x ,std::string y)
{
    return x.append(y);
}

std::string Add(std::string x ,std::string y)
{
    return x.append(y);
}

If we can specialize code using function overloading, why the need of Template specialization?

max66
  • 65,235
  • 10
  • 71
  • 111
  • 4
    This is really dependent on design and use-case, and there's no one "true" answer. – Some programmer dude Sep 23 '19 at 11:33
  • when an overload can do it then go for the overload, but thats just my personal opinion – 463035818_is_not_an_ai Sep 23 '19 at 11:34
  • What if you have 10 types that require the exact same calls and two that don't. Are you writing 12 overloads or rather 1 template and 2 specializations? I'd prefer the template – deW1 Sep 23 '19 at 11:34
  • @deW1 i was asking about the two specializations.we can specialize using template<>std::string Add(std::string x ,std::string y) { return x.append(y); }but we can also specialize using function overloading .right std::string Add(std::string x ,std::string y) { return x.append(y); } – Mohammed Ali Jahfer Sep 23 '19 at 11:38
  • @deW1 I dont think the answer to your (rhetorical?) question is that obvious. If I want to prevent a 13th type to be passed as parameter I prefer overloads rather than template vodoo (though I am still a c++11 guy where sfinae is still more arcane than it is nowadays) – 463035818_is_not_an_ai Sep 23 '19 at 11:38
  • who wrote `Add` in the first place? Why is it a template? That would be relevant to answer your question – 463035818_is_not_an_ai Sep 23 '19 at 11:39
  • I know, I was just giving an example of when it might be a bit clearer what the advantages are. In the end it's as @Someprogrammerdude said. – deW1 Sep 23 '19 at 11:46
  • Possible duplicate of [Template Specialization VS Function Overloading](https://stackoverflow.com/questions/7108033/template-specialization-vs-function-overloading) – xskxzr Sep 24 '19 at 03:36

3 Answers3

1

Because depending on the use case, you sometimes write containers/functions that are generic, i.e., they work for every type. Like for example std::vector. However, the meaning of a vector is not the same when you do std::vector<string> and std::vector<const char*> (while both represent strings), because one stores strings and the other stores pointers to null terminated strings. So how would you solve this problem from a design point of view?

Well, you either ignore the problem with this type, or prevent using this type, or write a specialization that makes this container work differently for this kind of type to achieve your design purpose. Similarly, you write a specialization for your function, depending on the problem you're trying to solve.

So, these template specialization are there to solve a specific kind of problem. If you don't need it, don't use it. You don't need to complicate your code for no reason.

The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189
1

If we can specialize code using function overloading.why the need of Template specialization

Because are different things with different behaviors.

A practical example.

The following example compile and link without problem

#include <string>

void foo (std::string const &)
 { }

int main ()
 {
   foo("abc");
 }

Observe that "abc" can be converted to a std::string but isn't a std::string (is a char const [4]).

So, calling a regular (non-template) function, the arguments are converted, when necessary.

Observe the following code

#include <string>

template <typename T>
void foo (T const &);

template <>
void foo (std::string const &)
 { }

int main ()
 {
   foo("abc");
 }

Now the code compile but doesn't link: foo() is a template (only declared) template function with only the std::string full specialization defined.

This time, the compiler deduce the type of the argument (char const [4], different from std::string) so gives a liner error because the general version of foo() isn't defined.

This way you can impose that foo() can be called only with a std::string, not with a value convertible to std::string.

You can obtain the same thing, mixing overloading and template, obtaining a compilation (not linking) error as follows

#include <string>

template <typename T>
void foo (T const &) = delete;

void foo (std::string const &)
 { }

int main ()
 {
   foo("abc");
 }

Now the non-template foo() can (theoretically) accept a char cont [4], but is declared (and deleted) the template version. So, given again that char const [4] isn't a std::string, the compiler give the precedence to the template version. That is deleted. So the compilation error.

max66
  • 65,235
  • 10
  • 71
  • 111
-1

It depends on the use case. Consider a function Add() which excepts two variables and returns the sum. Now based on a use case, the two variables can be integers or float. This can be achieved in following two ways :

Template <typename T>
T Add(T x, T y)
{
    return x + y;
}

OR, you can write two functions separately. One for integer and one for float parameters.

int Add(int x, int y)
{
    return x + y;
}

and,

float Add(float x, float y)
{
     return x + y;
}
Ayush Pallav
  • 919
  • 9
  • 18