A function name can only be overloaded if one or more of the following is true:
1) the versions have different return types,
2) the versions have a different number of arguments, or
3) the versions have arguments of different data types.
The main restriction with default values is that in calling the function you
cannot skip over parameters. If a function declaration looks like void f(int
a=1, float b=2.7, char c='z');, then you cannot call f() by specifying
only a and c. You must specify either none, a, a and b, or
all three arguments.
A function template can accept any data type. Keep in mind, however, that
depending on what your function does, it may not make sense to call some data
types. For instance, if << is not defined for a class, then there will be
an error in trying to print out an object.