Assuming:
R& operator+=( R& r, const V& v );
R& operator+=( R& r, V&& v );
R operator+=( R&& r, const V& v ) { r += v; return std::move(r); }
R operator+=( R&& r, V&& v ) { r += std::move(v); return std::move(r); }
we should have:
R operator+( R r, V const& v ) { return std::move(r)+=v; }
R operator+( R r, V && v ) { return std::move(r)+=std::move(v); }
R operator+( V const& v, R r ) { return std::move(r)+=v; }
R operator+( V && v, R r ) { return std::move(r)+=std::move(v); }
where I assume R is cheap-to-move, while += with a V&& is only marginally more efficient than a V const&.
Note that the return value of R operator+=( R&& r, ? ) should be a value. I implement it in terms of +=(const&,?), then just move into the return value.
This means you have to implement two += operators beyond the above boilerplate.
If there is no gain from a moved-from V we get:
R& operator+=( R& r, const V& v );
R operator+=( R&& r, const V& v ) { r += v; return std::move(r); }
R operator+( R r, V const& v ) { return std::move(r)+=v; }
R operator+( V const& v, R r ) { return std::move(r)+=v; }
3 boilerplate, one actually implemented function.
If you dislike R operator+=( R&& r, const V& v) we can rewrite this as:
R& operator+=( R& r, const V& v );
R operator+( R r, V const& v ) { return std::move(r+=v); }
R operator+( V const& v, R r ) { return std::move(r+=v); }
and similarly for the V&& cases if needed:
R& operator+=( R& r, V&& v );
R operator+( R r, V&& v ) { return std::move(r+=std::move(v)); }
R operator+( V&& v, R r ) { return std::move(r+=std::move(v)); }
We make a copy of the R in the signature of operator+ rather than internally; if we are going to copy it anyhow, may as well do it in the signature.
Want speed? Pass by value. is the technique used to remove the R const& and R&& overloads as redundant.