En C ++ 20, std::swap
se convierte en una constexpr
función.
Sé que la biblioteca estándar de verdad estuvo por detrás del lenguaje de marcado en las cosas constexpr
, pero en 2017, <algorithm>
era más o menos constexpr al igual que un montón de otras cosas. Sin embargo, - std::swap
no lo era. Vagamente recuerdo que hubiera algún defecto extraño idioma que impiden que estas marcas, pero me olvido de los detalles.
¿Puede alguien explicar esta manera concisa y clara?
La motivación: necesidad de comprender por qué puede ser mala idea para marcar una std::swap()
función -como constexpr
en C ++ 11 / C ++ 14 código.
La razón
(Debido a @NathanOliver)
Para permitir una constexpr
función de intercambio, usted tiene que comprobar - antes de crear instancias de la plantilla para esta función - que el tipo es intercambiado movimiento Urbanizable y mover asignable. Lamentablemente, debido a un lenguaje defecto sólo se resolvió en C ++ 20, que no se puede comprobar que, dado que las funciones miembro pertinentes no han sido definidos aún, en lo que se refiere al compilador.
la cronología
- 2016: Antonio Polukhin submitts propuesta P0202 , para marcar todas las
<algorithm>
funcionesconstexpr
. - El grupo de trabajo núcleo de los analizan Comité de Estándares de defectos GTC-1581 . Este problema hizo problemático tiene
constexpr std::swap()
y tambiénconstexpr std::invoke()
- ver explicación anterior. - 2017: Antonio revisa su propuesta un par de veces para excluir
std::swap
y algunas otras construcciones, y esto es aceptado en C ++ 17. - 2017: Una resolución para su emisión GTC-1581 se presenta como P0859 y aceptado por el Comité de Normas en 2017 (pero después de C ++ 17 enviado).
- Finales de 2017: Antony presenta una propuesta complementaria, P0879 , para hacer
std::swap()
constexpr después de la resolución del GTC-1581. - 2018: Se acepta la propuesta complementaria en C ++ 20 (?). Como señala Barry, también lo es la constexpr
std::invoke()
solución.
Su caso concreto
Puede utilizar constexpr
el canje si no se comprueba para mudarse constructibilidad y mover-transferible del mismo, sino más bien consultar directamente por alguna otra característica del tipo que asegura que en particular. por ejemplo, sólo los tipos primitivos y no hay clases o estructuras. O bien, en teoría, se podría renunciar a los controles y justo frente a los errores de compilación que pueden surgir, y con el comportamiento de escamosa conmutación entre los compiladores. En cualquier caso, no reemplace std::swap()
con ese tipo de cosa.