const B b4 = b1 + (b2 + b3);
According to the order of operations, the first subexpression to evaluate is b2 + b3. This invokes B::operator+, which returns a B object. More precisely, a temporary B object is returned, one that will be used to help evaluate this full expressions and then discarded. This is much like making notes on scratch paper as you work through a long calculation by hand.
The next subexpression to evaluate is b1 plus the temporary object. This invokes b1.operator+ with the temporary B object as the argument. When the operator's signature is
B operator+(B& b)
there is a problem because the C++ language states that a non-const reference cannot bind to a temporary object. That is, the reference parameter (B& b) does not match the temporary object. You can solve this by changing the reference from one that is not const-qualified to one that is.
B operator+(const B& b)
This version of the operator takes a const reference, which can bind to a temporary object. (Again, this is simply a rule of the language. You can debate the reasons for it, but the rule still stands.)
Note that this is not a full solution since addition tends to be symmetric. To accommodate the scenario where the left side of the parentheses is const-qualified, *this also needs to be const-qualified.
B operator+(const B& b) const
For more tips, see the basic rules and idioms for operator overloading. You might find that you don't necessarily want operator+ to be a member function.