2011-12-14 7 views
51

Los usuarios pueden agregar especializaciones explícitas al espacio de nombres std. Sin embargo, hay algunas plantillas de las que estoy explícitamente prohibido especializarme.¿Qué puedo y no puedo especializar en el espacio de nombres estándar?

¿Qué plantillas puedo y no puedo especializar?

+1

¿Qué es exactamente lo que está buscando en una respuesta? Realmente, si quieres especializarte en algo, debes consultar la especificación. La mayoría de los componentes de la Biblioteca estándar imponen requisitos a las especializaciones. Una respuesta completa de lo que puede y no puede especializarse y cuáles son las restricciones en especializaciones sería demasiado largo para una respuesta de desbordamiento de pila. –

+0

Por "especializar funciones", supongo que quiere decir "especializar plantillas de funciones"? Por cierto, ¿C++ 11 permite la especialización de plantilla de función parcial? – fredoverflow

+2

la especialización parcial de plantillas de funciones no está permitida; use la función de sobrecarga en su lugar. ver http://www.gotw.ca/publications/mill17.htm – mark

Respuesta

53

Citando libremente de la norma:

  • numeric_limits no se especializado para tipos estándar no aritméticas (por ejemplo complex<T>)

  • "[S] pecializations de shared_ptr serán CopyConstructible, CopyAssignable, y LessThanComparable [y] convertible 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 clase 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)

  • Las configuraciones regionales tienen ciertas especializaciones requeridas.

  • Todas las especializaciones de istreambuf_iterator tendrán un constructor de copia trivial, un constructor predeterminado de constexpr y un destructor trivial.

  • "No se especifica el efecto de instanciar la plantilla de clase complex para cualquier otro tipo que no sea flotante, doble o largo doble". 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, frase 1 (gracias @sehe y @curiousguy):

El comportamiento de un programa en C++ no está definido si se agrega declaraciones o definiciones al namespace std o al espacio de nombre dentro del espacio de nombres std 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 prohibido .

Y oración 2:

El comportamiento de un programa en C++ no está definido si se declara

  • una especialización explícita de cualquier función miembro de una plantilla de clase 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

  • especialización explícita o parcial de cualquier plantilla de clase miembro de una clase de biblioteca o plantilla de clase estándar.

Un programa puede crear una instancia explícitamente una plantilla definida en la biblioteca estándar sólo si la declaración depende del nombre de un tipo definido por el usuario y la creación de instancias cumple con los requisitos de la biblioteca estándar de la plantilla original.

+0

¡Espero que las especializaciones de 'shared_ptr',' weak_ptr' sean mucho más que CopySomething! – curiousguy

+1

"Un programa puede agregar una especialización de plantilla para cualquier plantilla de biblioteca estándar al espacio de nombre' std' solamente (...) la especialización ** cumple con los requisitos de biblioteca estándar para la plantilla original ** " – curiousguy

Cuestiones relacionadas