Reputation: 7648
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?
Upvotes: 39
Views: 43672
Reputation: 1006
So both overloading
and template
have their equal use .
one line difference
to about them is:
overloading
is used when we have various functions , doing SIMILAR
operations .
template
is used when we have various functions , doing IDENTICAL
operations .
There is very big differnce between "SIMILAR" and "IDENTICAL".
Upvotes: 3
Reputation: 490108
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.
Upvotes: 2
Reputation: 360
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);
}
Upvotes: 4
Reputation: 146910
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.
Upvotes: 8
Reputation: 14565
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.
Upvotes: 7
Reputation: 227390
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.
Upvotes: 44