In C++ as it's currently defined, when an operator overload is
applicable, the expression "a op b" is basically defined as calling
operator op(a, b), and similarly for unary functions. (When the operator
overload is a member function, 'a' is implicitly *this rather than
explicitly appearing in the function declaration, but it's the same
basic idea).
In a language derived from C90, that poses a problem, because several
expression types are defined as having a result which an lvalue (
(lvalue), *pointer_to_object, pointer_to_object[int], lvalue.member,
lvalue->member), but a function-call expression isn't one of them. C++
dealt with this problem by allowing such functions to be given a return
type which is a reference. Also, several expressions have, as their
defined behavior, modification of the value stored in one of the
operands (++, --, =, and compound assignment), which is inconsistent
with C's pass-by value semantics for function arguments. C++ dealt with
this problem by allowing function arguments to be references.
However, it would have been perfectly feasible to specify that when an
operator overload applies to one of those operators, the interpretation
would be different. for instance, a[b] could have been defined as
equivalent to *operator[](a,b), and ++a could have been define as
equivalent to operator++(&a).
Three of those operators already have special-case handling that doesn't
fit the general pattern I described above: "An expression x->m is
interpreted as (x.operator->())->m ..." (16.5.6p1) and "If the function
is a non-static member function with one parameter (which shall be of
type int) or a non-member function with two parameters (the second of
which shall be of type int), it defines the postfix increment operator
++ for objects of that type." (16.5.7p1), and similarly for --
(16.5.7p2).
It would have been no great additional difficulty providing special
handling for unary*, [], ++, --, and the assignment operators, too.
References weren't added to C++ because they were needed to implement
operator overloads. There are C compilers that provide operator
overloading as an extension, using precisely this approach.
References were added because they simplified the definition of such
overloads, and because Stroustrup liked the idea of allowing them in
other contexts as well.