C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 35:
35.1 What's the idea behind templates?
35.2 What's the syntax / semantics for a "class template"?
35.3 What's the syntax / semantics for a "function template"?
35.4 How do I explicitly select which version of a function template should get called?
35.5 What is a "parameterized type"?
35.6 What is "genericity"?
35.7 My template function does something special when the template type T is int or std::string; how do I write my template so it uses the special code when T is one of those specific types?
35.8 Huh? Can you provide an example of template specialization that doesn't use foo and bar?
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?
35.10 All those templates and template specializations must slow down my program, right?
35.11 So templates are overloading, right?
35.12 Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?
35.13 How can I avoid linker errors with my template functions? Updated!
35.14 How does the C++ keyword export help with template linker errors? Updated!
35.15 How can I avoid linker errors with my template classes? Updated!
35.16 Why do I get linker errors when I use template friends?
35.17 How can any human hope to understand these overly verbose template-based error messages?
35.18 Why am I getting errors when my template-derived-class uses a nested type it inherits from its template-base-class?
35.19 Why am I getting errors when my template-derived-class uses a member it inherits from its template-base-class?
35.20 Can the previous problem hurt me silently? Is it possible that the compiler will silently generate the wrong code?
35.21 How can I create a container-template that allows my users to supply the type of the underlying container that actually stores the values?
35.22 Follow-up to previous: can I pass in the underlying structure and the element-type separately?
35.23 Related: all those proxies must negatively reflect on the speed of my program. Don't they?
[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.