I once worked at a FAANG company where I had access to some of the leading C++ experts in the world (some were part of the international language committee). I emailed an internal C++ list asking whether a certain line of code would create a memory leak. It was a pure use of STL templates and casting. The experts could NOT agree whether I was doing it correctly. Some expected a leak, others didn't.
This true little story says everything about C++. JavaScript is full of these things too.
That was always it's strength. I started programming in 1976, trained in COBOL and ICL PLAN, used punched cards, and mop terminals once we got out of training. 100% of our programs were batch programs. There was a huge bias towards readability, so that anyone of us could read the source code and understand it. That readability was offset somewhat by the necessity to read and understand the core dumps produced when a program failed. At best you would be able to trace a failure to a specific line of code. Thus the habit of dry running programs was hard wired into you. When I left the government institution to move into commercial programming,it was still COBOL and batch programs until the early 80s.I spent 3 years on overnight support and that was when COBOL proved it's worth, you could pick up any previously unseen listing and the core dump and usually fix it pretty quickly, caveat it was always a tactical fix.
Overloading can be easily abused, but the very complicated expressions that can appear in programs for scientific/technical computing are immensely more readable when using operator overloading like in C++ instead of using named functions, like in languages that forbid operator overloading, e.g. Java.
In scientific/technical computing you have frequently, even in the same expression, dozens of different kinds of additions, multiplications, divisions, etc., between scalars, vectors, matrices, tensors, complex numbers, various kinds of physical quantities, and so on. Without operator overloading the expressions can become huge, extending on a great number of program lines and they can be very difficult to understand.
Also, Pascal's method of using a single kind of statement brackets, i.e. "begin" and "end" (renamed in C as "{" and "}"), which has been inherited from Algol 60, is wrong for program readability.
The right method has been introduced by Algol 68 and it was inherited by languages like Ada. In such languages there are several kinds of statement brackets, like in the UNIX shell, where "if" and "fi" are brackets for conditional statements, "do" and "done" are brackets for loops and "case" and "esac" are brackets for selection statements. This is much more readable, especially when there is a big loop that can not be seen in a single page of code, so you see only its end, which is also the end of many other kinds of program structures, like nested loops, conditional statements or selection statements.
To get the same readability in languages like Pascal and C, you can add comments to the final braces or "end" of the program structures, but this is much more cumbersome than in a language with several kinds of statement brackets, where the bracket pairs will normally be added automatically by your text editor.
It's precisely when "you have frequently, even in the same expression, dozens of different kinds of additions, multiplications, divisions, etc., between scalars, vectors, matrices, tensors, complex numbers, various kinds of physical quantities, and so on" that operator overloading should be driven by custom syntax macros. (E.g. in a Rust-like language you might define math_expr!(...), float_expr!(...), matrix_expr!(...) etc. syntax macros, each with its own special semantics for operator symbols.) That way a program can directly express the variety of overloading that's relevant in any given context, as opposed to relying on fragile hacks like special __add__ and __mul__ "traits" that are dispatched in a type-dependent way.
And, if you think the wrapper $type_expr! is too verbose, just use [blackboard bold M](...) or something.
Agda is my favorite example of a language that _judiciously_ uses Unicode symbols to express "concepts similar to something but is actually substantially different so let's not get them confused"... as opposed to other theorem proving languages of its time [1]
Fortran (FORmula TRANslation) was intended for a very peculiar subset of 'non-programmers': mathematicians, engineers and the like. It ends up being a pretty good impedance match for people who are use to dealing with terse forms of expression already.
This true little story says everything about C++. JavaScript is full of these things too.