What is the design rationale behind allowing this
const Foo& a = function_returning_Foo_by_value();
but not this
Foo&am
"What could possibly go wrong" is that you modify an object then instantly lose the changes, and the rule is therefore defined to help you not make such mistakes. You might think if you called the function again you would get an object with your changes, which of course you wouldn't because you modified a copy.
The typical case where you create a temporary then call a non-const method on it is when you are going to swap it:
std::string val;
some_func_that_returns_a_string().swap( val );
This can sometimes be very useful.