Operador de flecha izquierda de C++ (2016)

Idiomas de C++ lúdicos y “malvados”

  • La discusión reacciona a un operador personalizado de flecha izquierda como algo divertido, ingenioso y ligeramente terrorífico.
  • Se mencionan otros patrones “malvados”: llamar a delete this, invocar manualmente el destructor y luego hacer placement-new sobre this, y el conteo de referencias intrusivo.
  • Algunos sostienen que delete this es aceptable para objetos con conteo de referencias intrusivo o para Release al estilo COM; otros prefieren punteros inteligentes para ocultar este tipo de patrones.
  • Se citan lenguajes afines/de movimiento (por ejemplo, Rust) como algo que hace conceptualmente más seguro “destruir esto” que hacer delete manual de memoria.

Sobrecarga de operadores: poder frente a abuso

  • Muchos consideran que la sobrecarga de operadores está bien cuando se usa con buen gusto; los abusos se señalan como excepciones, no como la regla.
  • Ejemplos de usos controvertidos o lúdicos:
    • <</>> para flujos, mensajes de red e inserción en contenedores.
    • + para componer widgets de interfaz gráfica.
    • * para guardias RAII.
    • / para rutas del sistema de archivos.
    • Construcciones exóticas como “literales analógicos” y operadores tipo flecha o de renacuajo.
  • Algunos elogian bibliotecas (por ejemplo, de álgebra lineal) donde los operadores mejoran drásticamente la legibilidad.
  • Otros sostienen que los operadores en general fueron un error de diseño: demasiadas semánticas posibles (comportamiento ante overflow, etc.) y poca legibilidad frente a funciones con nombre.

Iostreams y formato

  • El uso de << para E/S se critica como un mal diseño que no se extendió más allá de la biblioteca estándar.
  • Algunos prefieren fuertemente APIs con cadenas de formato (std::format/std::print, estilo printf, o la biblioteca fmt) por su facilidad de uso y seguridad de tipos.
  • Contraargumento: los problemas de iostreams están en gran medida desvinculados de la sobrecarga de operadores en sí.

Functores, lambdas y operator()

  • Históricamente, operator() sobrecargado permitió functores/cierres; hoy las lambdas cubren la mayoría de los casos de uso.
  • Aun así, se considera que los tipos functor personalizados siguen siendo necesarios para algunos patrones (por ejemplo, internas de std::function, visitantes con múltiples sobrecargas, destructores con comportamiento).

Punteros a miembros y delegates

  • Los punteros a miembros de C++ se describen como confusos y definidos por la implementación.
  • Una postura los equipara inicialmente (aunque luego se matiza) a un “par” de puntero a instancia y función; otros insisten en que no contienen estado de instancia y solo codifican desplazamientos o datos de despacho.
  • Comparación con mecanismos de “delegate” o “fat pointer” en otros lenguajes (D, C#, Virgil, Delphi, Python):
    • Los fat pointers son elogiados por su simplicidad y por ofrecer cierres de primera clase.
    • El modelo más ligero de C++ se defiende como más flexible y barato, alineado con “no pagues por lo que no usas”, usando std::function como una abstracción más pesada cuando hace falta.
  • Surge un debate sobre compensaciones de rendimiento, despacho virtual, inlining y modelos de compilación.

Reflexiones generales sobre C++ y los operadores

  • Algunos participantes expresan afecto por el poder y la creatividad de C++; otros lo califican de excesivamente complejo, incluso de “comedia” o “abominable”.
  • Hay una tensión recurrente entre la expresividad ingeniosa (operadores personalizados, trucos) y la legibilidad y mantenibilidad del código a largo plazo.