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.