|
||||
|
Section 35:
|
[35.9] But most of the code in my template function is the same; is there some way to get the benefits of template specialization without duplicating all that source code?
Yes. For example, suppose your template function has a bunch of common code along with a relatively small amount of T-specific code (conceptual only; not C++):
template<typename T>
void foo(T const& x)
{
... common code that works for all T types ...
switch (typeof(T)) { ← conceptual only; not C++
case int:
... small amount of code used only when T is int ...
break;
case std::string:
... small amount of code used only when T is std::string ...
break;
default:
... small amount of code used when T is neither int nor std::string ...
break;
}
... more common code that works for all T types ...
}
If you blindly applied the advice from the FAQ
on template specialization, you would end up duplicating all that code
before and after the pseudo-switch statement. The way to get the best of both
worlds — to get the benefits of T-specific pieces without
duplicating the entire function, is to extract the pseudo-switch statement
portion into a separate function foo_part(), and
use template specialization on that
separate function:
template<typename T> inline void foo_part(T const& x)
{
... small amount of code used when T is neither int nor std::string ...
}
template<> inline void foo_part<int>(int const& x)
{
... small amount of code used only when T is int ...
}
template<> inline void foo_part<std::string>(std::string const& x)
{
... small amount of code used only when T is std::string ...
}
The main foo() function would be a simple template — no
specializations. Note that the pseudo-switch statement has been replaced by a
call to foo_part():
template<typename T>
void foo(T const& x)
{
... common code that works for all T types ...
foo_part(x);
... more common code that works for all T types ...
}
As you can see, the body of foo() now doesn't mention any particular
T. It all gets figured out automatically. The compiler generates
foo for you based on type T, and will generate the correctly
typed foo_part function based on the actual compile-time known type of
the x argument. Proper specializations of foo_part will be
instantiated.
|
|||