62

Users are allowed to add explicit specializations to the std namespace. However, there are a few templates that I am explicitly forbidden from specializing.

What templates can and can't I specialize?

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • 1
    What, exactly, are you looking for in an answer? Really, if you want to specialize something, you must consult the specification. Most Standard Library components impose requirements on specializations. A complete answer of what you can and cannot specialize and what the restrictions are on specializations would be far too long for a Stack Overflow answer. – James McNellis Dec 15 '11 at 00:06
  • By "specialize functions", I assume you mean "specialize function templates"? By the way, does C++11 allow partial function template specialization? – fredoverflow Dec 15 '11 at 07:42
  • 2
    partial specialization of function templates is not allowed, use function overloading instead. see http://www.gotw.ca/publications/mill17.htm – mark Dec 15 '11 at 09:38

1 Answers1

67

Quoting loosely from the standard:

  • numeric_limits shall not be specialized for non-arithmetic standard types (e.g. complex<T>)

  • "[S]pecializations of shared_ptr shall be CopyConstructible, CopyAssignable, and LessThanComparable [and] convertible to bool."

  • "Specializations of weak_ptr shall be CopyConstructible and CopyAssignable."

  • "[T]emplate specializations [of std::hash] shall meet the requirements of class template hash."

  • Anything in <type_traits>: "The behavior of a program that adds specializations for any of the class templates defined in this subclause is undefined unless otherwise specified." (only some specializations of common_type are explicitly allowed)

  • Locales have certain required specializations.

  • All specializations of istreambuf_iterator shall have a trivial copy constructor, a constexpr default constructor, and a trivial destructor.

  • "The effect of instantiating the class template complex for any type other than float, double, or long double is unspecified." I take it that means that defining such other specializations is pointless.

  • "Specializations and instantiations of the atomic template shall have a deleted copy constructor, a deleted copy assignment operator, and a constexpr value constructor."

  • "The class templates unary_function and binary_function are deprecated. A program shall not declare specializations of these templates."

And of course the overarching clause 17.6.4.2.1, sentence 1 (thanks @sehe and @curiousguy):

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

And sentence 2:

The behavior of a C++ program is undefined if it declares

  • an explicit specialization of any member function of a standard library class template, or

  • an explicit specialization of any member function template of a standard library class or class template, or

  • an explicit or partial specialization of any member class template of a standard library class or class template.

A program may explicitly instantiate a template defined in the standard library only if the declaration depends on the name of a user-defined type and the instantiation meets the standard library requirements for the original template.

Community
  • 1
  • 1
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • I expect specialisations of `shared_ptr`, `weak_ptr` to be much more than CopySomething! – curiousguy Dec 15 '11 at 00:07
  • 2
    "A program may add a template specialization for any standard library template to namespace `std` only (...) the specialization **meets the standard library requirements for the original template**" – curiousguy Dec 15 '11 at 00:14
  • 4
    How about specialising `default_delete` in the `std` namespace? – Ela782 Oct 04 '18 at 20:52