5

When do we use template specializations for in C++, if not for SFINAE or metaprogramming? type_traits, enable_if and others rely on it a lot, but I'm more curious about situations which are more "obvious" uses of templates - type-agnostic algorithms and objects.

One can easily create an artificial example of algorithm which does completely different things for different types, so I'd like to limit the scope to more "real-life" scenarios. Specifically, the following properties should be satisfied:

  1. One can formulate an invariant of a generic version of template (so it makes sense to talk about specialization), and
  2. Specialized version do not violate any invariants of the generic version (if it does, it's probably a bad specialization and a separate class/function should be created instead).

I have three examples in my mind:

  • std::vector<bool>. It's known to have different interface from generic vector (1, 2) and therefore I consider it a bad example - it does not satisfy property 2.
  • std::hash. Despite it does not have "generic" implementation, it has "generic" invariant.
  • std::swap. It satisfies both properties.

These examples, though, look very specific to me. I'm wondering if it's possible to describe when one should use template specialization. E.g. "if you have a type-agnostic container which has a strictly better implementation for some specific type" is probably true, but, again, rather specific.

  • 2
    This largely reads like a rant “vector<bool> sucks, am I right?” (which, though true, is unrelated to specializations). The remaining question could be improved (or even answered) by doing a bit more research. Perhaps you'd like to learn more about templates, the difference between class- and function-templates, interactions between function template specializations and function overloading, and most importantly: using (partial) specializations for SFINAE. E.g. the C++11 type_traits header uses a lot of template specializations. – amon Mar 5 '17 at 15:29
  • 1
    @amon Thank you. I'll add more context in the question and remove unrelated details and clarifications. – yeputons Mar 5 '17 at 15:36
  • 2
    When embedding a scripting language, you might define template<class T> T getArgument(LanguageInterpreter *i, int argumentIndex) = delete; and then specialize it for the particular argument types you need. (E.g. template<> string getArgument(LanguageInterpreter *i, int index) {return i->getArgString(index);}) – immibis Mar 6 '17 at 3:55
  • 4
    I am not sure what you are asking here, since AFAIK "template meta programming" is by definition any usage of template features of C++. So using "template specializations" is trivially a form of "template meta programming", real world scenario or not. – Doc Brown Mar 6 '17 at 16:10
2

When one should use template specialization, if not for metaprogramming?

The "classical" thing, and even the one you mention at the end, is to refine a given generic implementation for a specific (set of) types.

Prime example here would be container or algorithm "optimizations" for trivial types. (See e.g. std::copy)

There's nothing meta about this as far as I can tell: For some types, a given specialized version will be objectively better, keeping all requirements of the generic version, so it will be implemented as soon as needed.

0

At some point, some C++ standard libraries contained specializations of the containers for any T*, making them thin wrappers around containers of void*.

This was done to reduce generated code duplication.

Some modern linkers are capable of eliminating this code duplication automatically, thus reducing the need for such workarounds.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.