The problem of returning a reference to a local object is that the caller will receive something that is already dead on arrival.
When you exit from a function all locals are destroyed, so you cannot keep using references to them.
Code like
const X& res = a+b;
would works if the operator returns by value because there is a specific rule in the language that says that temporary objects bound to references will be kept alive until the reference itself is destroyed.
Returning a reference instead is different because the lifetime of the object is a responsibility of the called operator, not of the caller. So the end result will be a reference that is bound to an object that has already been destroyed.
Even just
X res;
res = a+b;
would not work, because when the operator call returns the object is destroyed before the assignment is made to res
. Same would be in case of a copy constructor X res = a+b;
.