c++ - relacionales - ¿Por qué no sobrecargar el operador+=() para std:: vector?
sobrecarga de operadores unarios en c++ (4)
Además de lo que otros mencionaron acerca de que esta sintaxis no es intuitiva y, por lo tanto, es propensa a errores, también va en contra de una buena regla de diseño que hace que los algoritmos generales se apliquen a varios contenedores de funciones libres, y los algoritmos específicos de contenedor - funciones de miembro. La mayoría de los contenedores siguen esta regla, a excepción de std::string
, que recibió un montón de información de Herb Sutter por su diseño monolítico.
Empecé a aprender C ++, por lo que no sé en mi falta de conocimiento / experiencia por qué algo tan aparentemente simple para un novato como lo que estoy a punto de describir no está ya en la STL. Para agregar un vector a otro vector tienes que escribir esto:
v1.insert(v1.end(), v2.begin(), v2.end());
Me pregunto si en el mundo real las personas simplemente sobrecargan el operador + = para hacer esto menos detallado, por ejemplo, para el efecto de
template <typename T>
void operator+=(std::vector<T> &v1, const std::vector<T> &v2) {
v1.insert(v1.end(), v2.begin(), v2.end());
}
entonces tú puedes
v1 += v2;
También tengo esta configuración para push_back a "+ =" un solo elemento hasta el final. ¿Hay alguna razón para que estas cosas no se hagan o se eviten específicamente por personas que son competentes en C ++?
Creo que la razón principal es que la semántica de +=
no es obvia. Tiene el significado que tiene aquí, pero también hay un significado igualmente válido, que es la adición de elementos a los elementos de vectores de igual tamaño. Debido a esta ambigüedad, asumo que decidieron que era mejor confiar en que el usuario llamara a insert
directamente.
Este es realmente un caso en el que me gustaría ver esta funcionalidad en forma de una sobrecarga de append()
. operator+=
es un poco ambiguo, ¿te refieres a agregar los elementos de cada vector entre sí? ¿O te propones añadir?
Sin embargo, como dije, habría dado la bienvenida: v1.append(v2);
Es claro y simple, no sé por qué no está allí.
Los operadores deben estar sobrecargados solo cuando no esté cambiando el significado de esos operadores. *
Lo que eso significa es, por ejemplo, que si no hay una definición matemática del producto de dos objetos, no sobrecargue el operador de multiplicación de esos objetos. Si hubiera una correspondencia matemática, la sobrecarga de operadores puede hacer que sea más conveniente usar una clase al permitir que las ecuaciones se expresen en la forma a * b + c en lugar de las más detalladas (a.multiply (b)). Add (c) Where se utilizan operadores de suma y multiplicación, la suma y la multiplicación deben ser la intención. Cualquier otro significado es más que probable que confunda a otros. Algunos otros tipos en los que los operadores de sobrecarga son aceptables (y, en mi opinión, preferibles ) son los punteros inteligentes, los iteradores, los números complejos, los vectores y los grandes signos.
Esto se desprende de uno de los objetivos de diseño de C ++, que debería ser posible definir clases que sean tan fáciles de usar como los tipos integrados. Por supuesto, hay operadores que puede definir en clases que tampoco son conceptos matemáticos. Es posible que desee sobrecargar los operadores == y! = En lugar de escribir un método isEqual, y puede querer sobrecargar = porque el operador de asignación predeterminado del compilador no es lo que desea.
Por otro lado, sobrecargar a un operador para hacer algo inesperado, como definir ^ para traducir una cadena a japonés, es oscuro y peligroso. Sus compañeros programadores no se alegrarán de descubrir que lo que parecía una comparación exclusiva o exclusiva era en realidad algo muy diferente. La solución entonces es escribir sus clases para facilitar la escritura de un código claro y mantenible , ya sea que eso signifique utilizar la sobrecarga del operador o evitarlo.
Agregar dos vectores es demasiado ambiguo como para justificar la definición de un operador. Como han demostrado otros, muchas personas tienen ideas diferentes de lo que esto significa, mientras que para una cadena se entiende universalmente que agregar dos cadenas juntas significa concatenación. En su ejemplo, no está del todo claro si desea hacer un agregado inteligente en todos los elementos, agregar un elemento al final o concatear dos vectores juntos. Aunque puede ser más conciso hacerlo de esa manera, usar la sobrecarga del operador para crear su propio lenguaje de programación no es la mejor manera de hacerlo.
* Sí, sé que Stroustrup ha sobrecargado << y >> para realizar operaciones de transmisión en lugar de cambios de bits. Pero esos no se usaron a menudo en comparación con los operadores de aritmética y de puntero en primer lugar, y se podría argumentar que ahora que todos saben cómo usar cout, generalmente se entiende que << y >> son los operadores insertadores y extractores. (Originalmente intentó usar solo <y> para entrada y salida, pero el significado de esos operadores estaba tan arraigado en la mente de todos que el código era ilegible).