Sometime I want to write two templates like:
template <typename Type1>
class A{
...
};
template <typename Type1, typename Type2>
class A{
...
};
But it seems that it is illegal to have two templates shared the same name but have different parameters. I have to name it like A_1
, A_2
. I think it might be useful if I can do this especially when implementing Functors.
Why C++ doesn't allow this? Does it difficult to implement or have ambiguity in some circumstance? Will this be supported on later version of C++?
You may overload a function template either by a non-template function or by another function template. The function call f(1, 2) could match the argument types of both the template function and the non-template function.
In general, templates make the language much more complicated (and difficult to implement correctly!). Templates were not intentionally designed to be Turing-complete, but they are anyway -- thus, even though they can do just about anything, using them may turn out to be more trouble than it's worth.
Both function overloading and templates are examples of polymorphism features of OOP. Function overloading is used when multiple functions do quite similar (not identical) operations, templates are used when multiple functions do identical operations.
Templates are very useful when implementing generic constructs like vectors, stacks, lists, queues which can be used with any arbitrary type. C++ templates provide a way to reuse source code as opposed to inheritance and composition which provides a way to reuse object code.
It is extremely useful, but like you say, C++ doesn't allow you to do this directly. However, you can do almost the same thing with partial specialisation.
This is particularly easy if you use variadic templates in C++11, as you can do the following:
template <typename... T>
struct A; // Declared but not defined
template <typename T, typename U>
struct A<T, U>
{
// definition of the two-parameter case
};
template <typename T>
struct A<T>
{
// definition of the one-parameter case
};
Effectively, this allows you to have A<T, U>
and A<T>
as completely separate types. Attempting to instantiate an A
with more template parameters will lead to a compile error as the general case is undefined (you could use a static_assert
to give a nice error message if you wanted).
Something similar can be achieved in C++03 using default template parameters (set to an empty dummy struct, or void
), but the C++11 version is much nicer IMO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With