function overloading vs function templates - C++
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.
HalfWebDev
I hack Javascript and want to maximise the use of it in my career in varied and challenging forms.
Updated on January 30, 2020Comments
-
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 over 11 yearsBut still that can be achieved with function templates too .
-
Mike Corcoran over 11 yearsi 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 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 over 11 yearsin 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 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 over 11 yearsAdding a default value for one of the parameters would be better:
void foo( int j, int i = 0 );
-
Jonathan. over 8 yearsWhat do you mean overloading allows you to use different syntax?
-
Jonathan. over 8 yearsAh 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 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 about 4 yearsSo, 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 about 4 yearsCouldn'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" ?