Los compiladores de C++ generan automáticamente constructores de copia y operadores de asignación de copia. ¿Por qué no también swap
?¿Por qué no hay métodos swap() generados por el compilador en C++ 0x?
Estos días el método preferido para la aplicación del operador de copia-asignación es el idioma de copiar y swap:
T& operator=(const T& other)
{
T copy(other);
swap(copy);
return *this;
}
(ignoring the copy-elision-friendly form that uses pass-by-value).
Esta expresión idiomática tiene la ventaja de ser transaccional frente a excepciones (suponiendo que la implementación swap
no arroja). Por el contrario, el operador predeterminado de copia-asignación generado por el compilador recurrentemente hace la copia-asignación en todas las clases base y miembros de datos, y eso no tiene la misma excepción-garantías de seguridad.
Mientras tanto, la implementación de swap
métodos manual es tedioso y propenso a errores:
- Para garantizar que
swap
no tira, se debe implementar para todos los miembros no pod en la clase y en las clases de base, en sus miembros no POD, etc. - Si un mantenedor agrega un nuevo miembro de datos a una clase, el mantenedor debe recordar modificar el método
swap
de esa clase. No hacerlo puede introducir errores sutiles. Además, dado queswap
es un método ordinario, los compiladores (al menos ninguno que conozco) no emiten advertencias si la implementaciónswap
está incompleta.
¿No sería mejor si el compilador generó los métodos swap
automáticamente? Entonces la implementación implícita de copia-asignación podría aprovecharlo.
La respuesta obvia es probablemente: el modismo copiar y cambiar no existía cuando se desarrolló C++, y hacer esto ahora podría romper el código existente.
Sin embargo, tal vez la gente podría optar por dejar que el compilador generar swap
utilizando la misma sintaxis que C++ 0x utiliza para controlar otras funciones implícitas:
void swap() = default;
y entonces no puede haber reglas:
- Si hay un método
swap
generado por el compilador, se puede implementar un operador implícito de copia-asignación utilizando copy-and-swap. - Si no hay un método
swap
generado por el compilador, se implementará un operador implícito de copia-asignación como antes (invocando la asignación de copia en todas las clases base y en todos los miembros).
¿Alguien sabe si tales cosas (locuras?) Se han sugerido al comité de estándares de C++, y si es así, ¿qué opiniones tenían los miembros del comité?
me he preguntado lo mismo una serie de.! veces, especialmente porque 'swap' generalmente se implementa en términos de' intercambio' de todos los miembros de datos de todos modos, por lo que es muy parecido a 'copiar' o' asignación' y las nuevas versiones de 'movimiento' –
En C++ 0x,' swap 'debe ser algo así como' template void swap (T & x, T & y) {T temp (std :: mover (x)); x = std :: move (y); y = std :: move (temp);} 'que esencialmente hará lo que cualquier función de intercambio escrita personalizada haría. Estoy de acuerdo con su pregunta, pero los cambios personalizados ya no son necesarios, con el ction de referencias r-value. 'std :: swap' funcionará muy bien. –
GManNickG
Sospecho que la razón por la que no está en C++ 98 es que las únicas funciones generadas por el compilador en C++ están ahí para hacer que las clases se comporten como estructuras C: puedes declararlas, destruirlas y copiarlas. Por muy útil que sea un 'swap' predeterminado o' operator '' por defecto (y ambos podrían implementarse mediante operaciones de campo) el estándar C++ quería un mínimo de funciones predeterminadas, por lo que hay menos para suprimir si no lo quiere . La sintaxis C++ 0x 'function = something' podría ser una opción mucho mejor, ya que es opcional. En principio, podría tener incluso diferentes opciones de canjes seguros y no seguros. –