una todas resueltos programas programar principiantes parametros para las funciones funcion ejercicios ejemplos declara con como codigos avanzados c++ std template-specialization function-templates c++20

todas - programas en c++ ejemplos avanzados



¿Ya no se permitirá la especialización de plantillas de función en estándar para tipos definidos por programa en C++ 20? (2)

Cita de cppreference.com :

Añadiendo especializaciones de plantillas.

Se permite agregar especializaciones de plantilla para cualquier biblioteca | clase estándar (desde C ++ 20) | plantilla para el espacio de nombres estándar solo si la declaración depende de al menos un tipo definido por el programa y la especialización satisface todos los requisitos de la plantilla original, excepto cuando dichas especializaciones estén prohibidas.

¿Significa que a partir de C ++ 20, ya no se permitirá agregar especializaciones de plantillas de función al espacio de nombres std para los tipos definidos por el usuario? Si es así, implica que muchas partes del código existente pueden romperse, ¿no es así? (Me parece que es una especie de cambio "radical"). Además, inyectará en tales códigos un comportamiento indefinido, que no activará errores de compilación (es de esperar que las advertencias).


Realmente no es tan radical. Este cambio se basa en este documento de Walter E. Brown . El documento entra en razón bastante profundamente, pero en última instancia se reduce a esto:

  1. La especialización de plantillas de funciones es bastante pobre como punto de personalización. Sobrecarga y ADL son mucho mejores en ese sentido. Hay otros puntos de personalización discutidos en el documento también.
  2. La biblioteca estándar no se basa demasiado en este punto de personalización deficiente.
  3. El cambio de redacción que se implementó en realidad permite agregar declaraciones completas al espacio de nombres estándar (no solo a las especializaciones) donde se permite explícitamente. Así que ahora hay mejores puntos de personalización.

Dados los números 1 y 2, es poco probable que el código existente se rompa. O al menos, no es suficiente para que esto sea un problema importante. El código que usaba auto y register también se "rompió" en el pasado, pero esa cantidad minúscula de código C ++ no detuvo el progreso.


Tal como está ahora, definitivamente se ve así. Anteriormente [namespace.std] contenía

Un programa puede agregar una especialización de plantilla para cualquier plantilla de biblioteca estándar al espacio de nombres estándar 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.

Mientras que el proyecto actual declara

A menos que se prohíba explícitamente, un programa puede agregar una especialización de plantilla para cualquier plantilla de clase de biblioteca estándar a namespace std siempre que (a) la declaración agregada dependa de al menos un tipo definido por el programa y (b) la especialización cumpla con los requisitos de biblioteca estándar para el plantilla original

énfasis mio

Y se parece al papel ¡ No especializarás las plantillas de funciones estándar! por Walter E. Brown es responsable de ello. En él, él detalla una serie de razones por las cuales esto debería ser cambiado, como:

  • Herb Sutter: “las especializaciones no participan en la sobrecarga. [...] Si desea personalizar una plantilla de base de funciones y desea que esa personalización participe en la resolución de sobrecarga (o, para que siempre se use en el caso de coincidencia exacta), conviértala en una función antigua, no en una especialización. Y, si proporciona sobrecargas, evite también proporcionar especializaciones ".
  • David Abrahams: “está mal usar la especialización de plantilla de función [porque] interactúa de manera incorrecta con las sobrecargas. [...] Por ejemplo, si especializa el estándar std::swap for std::vector<mytype>& , su especialización no se elegirá sobre el swap específico del vector estándar, porque las especializaciones no se consideran durante la resolución de sobrecarga . ”
  • Howard Hinnant: "este problema se ha solucionado durante mucho tiempo. . . . Ignore la opinión experta de Dave / responda en esta área bajo su propio riesgo ”.
  • Eric Niebler: "[debido a] la manera decididamente extraña que C ++ resuelve las llamadas a funciones en las plantillas. . . , [w] e hacemos una llamada no cualificada a swap para encontrar una sobrecarga que pueda definirse en espacios de nombres [...] asociados, y lo hacemos using std::swap para que, en el off - Si no existe tal sobrecarga, encontramos la versión predeterminada definida en el espacio de nombres estándar ".
  • Estándar de codificación de C ++ de alta integridad: “La resolución de sobrecarga no tiene en cuenta las especializaciones explícitas de las plantillas de función. Solo después de que la resolución de sobrecarga haya elegido una plantilla de función, se considerarán las especializaciones explícitas ".