c++ c++11 std explicit-specialization

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 a bool ."

  • "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 de common_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 y binary_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?