The problem here isn't about the ref but rather the way
properties are implemented with +=. I believe this is one of the
older still-standing D bugs.
It rewrites your expresssion to be
f.foo() += 5;
and the problem is the foo getter returns a plain int which isn't
an lvalue.
If your getter returned a ref, it would work, but it wouldn't
call the setter.
The setter is (right now, and probably for a while to come) only
called on plain assignment.
f.foo = f.foo + 5;
That should work with your current code, being rewritten as
f.foo(f.foo() + 5), but += won't.
But anyway if you just use the getter and have it return a ref,
you can use += but then you lose the setter function.