c++ - ¿Qué puedo y no puedo especializar en el espacio de nombres estándar?
c++11 std (1)
Citando vagamente del estándar:
numeric_limits
no debe estar especializado para tipos estándar no aritméticos (p. ej.complex<T>
)"[S] las especializaciones de
shared_ptr
serán CopyConstructible, CopyAssignable y LessThanComparable [y] convertibles abool
.""Las especializaciones de
weak_ptr
serán CopyConstructible y CopyAssignable"."[T] las especializaciones [de
std::hash
] deberán cumplir los requisitos del hash de plantilla de clase".Cualquier cosa en
<type_traits>
: "El comportamiento de un programa que agrega especializaciones para cualquiera de las plantillas de clases definidas en esta subcláusula no está definido a menos que se especifique lo contrario". (solo algunas especializaciones decommon_type
están explícitamente permitidas)Los locales tienen ciertas especializaciones requeridas .
Todas las especializaciones de
istreambuf_iterator
tendrán un constructor de copia trivial, un constructor por defecto constexpr y un destructor trivial."El efecto de instanciar el
complex
plantilla de clase para cualquier tipo que no sea float, double o long double no está especificado". Supongo que eso significa que definir tales otras especializaciones no tiene sentido."Las especializaciones y las instancias de la plantilla
atomic
tendrán un constructor de copia eliminado, un operador de asignación de copia eliminado y un constructor de valor constexpr"."Las plantillas de clase
unary_function
ybinary_function
están en desuso. Un programa no debe declarar especializaciones de estas plantillas".
Y, por supuesto, la cláusula general 17.6.4.2.1, oración 1 (gracias @sehe y @curiousguy):
El comportamiento de un programa C ++ no está definido si agrega declaraciones o definiciones al espacio de nombres std o a un espacio de nombres dentro del espacio de nombres estándar, a menos que se especifique lo contrario. Un programa puede agregar una especialización de plantilla para cualquier plantilla de biblioteca estándar al espacio de nombre std solo si la declaración depende de un tipo definido por el usuario y la especialización cumple con los requisitos de biblioteca estándar para la plantilla original y no está explícitamente prohibida.
Y oración 2:
El comportamiento de un programa C ++ no está definido si declara
una especialización explícita de cualquier función miembro de una plantilla de clase de biblioteca estándar, o
una especialización explícita de cualquier plantilla de función miembro de una clase de biblioteca estándar o plantilla de clase, o
una especialización explícita o parcial de cualquier plantilla de clase miembro de una clase de biblioteca estándar o plantilla de clase.
Un programa puede instanciar explícitamente una plantilla definida en la biblioteca estándar solo si la declaración depende del nombre de un tipo definido por el usuario y la instanciación cumple con los requisitos de la biblioteca estándar para la plantilla original.
Los usuarios pueden agregar especializaciones explícitas al std
nombres std
. Sin embargo, hay algunas plantillas de las que estoy explícitamente prohibido especializarme.
¿Qué plantillas puedo y no puedo especializar?