function overloading vs function templates - C++

32,790

Solution 1

Templates provide an advantage when you want to perform the same action on types that can be different. A simple example:

template <typename T>
T foo(const T& a, const T& b) { return a + b; }

You can use overloading when you want to apply different operations depending on the type:

struct Foo{ void foo() const {} };

void foo(int i) { std::cout << "i = " << i << "\n"; }
void foo(const Foo& f) { f.foo(); }

You could achieve the above using templates and template specializations, but such specializations should represent a few exceptions to the general case.

Solution 2

Templates cannot take varying numbers of arguments. Overloads can. In addition, a template indicates that you can operate on any data type, but it's pointless to represent this when in fact, the vast, vast majority of templates would be specializations only (in your system). Also, overloads can be virtual and template specializations cannot. Nor can specializations differ in their signatures from the base.

template<typename T> void foo(T& t);
template<> void foo<std::string>(std::string* ptr); // Illegal
void foo(std::string* ptr); // Legal

This would severely constrain what kinds of overload you could produce compared to the current system.

Solution 3

You generally use templates when you want to do the same set of operations on many different data types.

You generally would use function overloading when you want to do different operations on certain sets of data.

the advantage of templates in a situation where you want to do the same set of operations on many different data types, is that the compiler will handle for you at compile time any possible new type you may create in the future that uses the templated function. if you were to use function overloading, you'd have to create a new function overload every time you created a new type that you wanted to pass to the specific function.

Solution 4

Just an addition to juanchopanza's answer:

With function overloads you can also vary the number of arguments, which can be handy.

A simple example, if you have some function with the following declaration:

void foo(int i, int j);

But you often call foo with first argument 0, you could write the following function which saves you some typing.

void foo(int j) {
  foo(0, j);
}

Solution 5

Templates (normally) require that you use identical syntax to carry out the operations on all (supported) types.

Function overloading is (or should be) used similarly, but allows you to use different syntax to carry out the operations for different types. That is to say that (although you don't have to) you can represent the values in different ways. One obvious example would be what are called atan and atan2 in the C library. With atan, we pass the ratio of the "rise to the "run", and we get back the angle that ratio represents. With atan2 we pass the values for the rise and run separately (which computes roughly the same result, but since it's given slightly more input data, can produce a more complete result as well).

Although these are implemented as entirely separate functions in C, if they were written in C++ from the beginning it would be entirely appropriate to use a single name (e.g., atan) overloaded for both a one and two parameters:

double atan(double);           // equivalent to current atan
double atan(double, double);   // equivalent to current atan2

Templates (short of specialization, which is pretty much just overriding what templates themselves provide) doesn't provide for differences in calling syntax like this.

Overloading is also more constrained -- you provide one overload for each specific type you want to support (though if you take a pointer or reference those can also support derived types). With templates, a single template can (at least potentially) apply to any type.

Share:
32,790
HalfWebDev
Author by

HalfWebDev

I hack Javascript and want to maximise the use of it in my career in varied and challenging forms.

Updated on January 30, 2020

Comments

  • HalfWebDev
    HalfWebDev over 4 years

    In books on C++, why are we taught to use function overloading when we have templates at our disposal in C++?

    Wouldn't it be better to show the effective (and correct) use of templates? As opposed to where function overloading is taught in most books on C++?

    Or, are there good reasons to use one instead of the other?

  • HalfWebDev
    HalfWebDev over 11 years
    But still that can be achieved with function templates too .
  • Mike Corcoran
    Mike Corcoran over 11 years
    i updated the answer to answer that specific issue. basically, you cannot know at the time you create your function overloads, every possible type that may be created in the future that you might wish to pass to your function. templates can help solve that problem.
  • PRouleau
    PRouleau over 11 years
    @kushal Yes but with template, the compiler create a new function for every type used, while with function overloading you keep control of how many function exist in the final program. Template makes the program bigger. A function printValue(int) is enough to handle short and signed char too.
  • umps
    umps over 11 years
    in C+11 templates can technically take multiple arguments, en.wikipedia.org/wiki/Variadic_template, but they are not as easy to use compared to function overloading.
  • Puppy
    Puppy over 11 years
    @umps: You could specialize a variadic template for any argument count, I guess. But they weren't around when overloading was introduced.
  • SingerOfTheFall
    SingerOfTheFall over 11 years
    Adding a default value for one of the parameters would be better: void foo( int j, int i = 0 );
  • Jonathan.
    Jonathan. over 8 years
    What do you mean overloading allows you to use different syntax?
  • Jonathan.
    Jonathan. over 8 years
    Ah so you mean when overloading the function arity can be different, but with templates, theres only one definition so only one arity for all types.
  • greggo
    greggo about 7 years
    @SingerOfTheFall but you can only supply defaults at the end, it may not be desirable to reorder parameters to allow this. And functions with default parameters don't actually create new functions; for instance I can do void (*func_ptr)(int) = foo; with the example above, but not if it's your example with a default.
  • M.Ionut
    M.Ionut about 4 years
    So, basically should we use overloading when we want to do different things ("within the same function"; double comas because it is not actually the same function) based on the types that we pass the function? Just like @Mike Corcoran (below answer) says, right?
  • M.Ionut
    M.Ionut about 4 years
    Couldn't you do that, namely vary the number of arguments, with templates, also? I am thinking to pass the "templated-types" arguments , followed by int argc, const char * argv[] ? Or am I totally wrong here? Also, could you be more specific @greggo. What do you mean by "but not if it's your example with a default" ?