如何在C ++中定义(重载)两个类之间的对称二元运算符,考虑r值?

时间:2016-11-15 15:27:41

标签: c++ c++11 operator-overloading rvalue

我想要的是:R = V + R = R + V. 我是怎么做的:

R operator+(const R &r, const V &v) { return R(r) += v; }
R operator+(R &&r, const V &v) { return R(r) += v; }
R operator+(const R &r, V &&v) { return R(r) += v; }
R operator+(R &&r, V &&v) { return R(r) += v; }

R operator+(const V &v, const R &r) { return r + v; }
R operator+(V &&v, const R &r) { return r + v; }
R operator+(const V &v, R &&r) { return r + v; }
R operator+(V &&v, R &&r) { return r + v; }

有更短的路吗?

2 个答案:

答案 0 :(得分:2)

因为您无论如何都会从rconst R&创建R&&的实例,这将缩短4行:

R operator+(R r, const V& v) { return std::move(r += v); }
R operator+(R r, V&& v) { return std::move(r += std::move(v)); }

R operator+(const V& v, R r) { return std::move(r += v); }
R operator+(V&& v, R r) { return std::move(r += std::move(v)); }

但是,我认为除非R::operator+=(V&&)R::operator+=(const V&)的实施不同,否则在所有情况下这都足够了:

R operator+(R r, const V& v) { return std::move(r += v); }

R operator+(const V& v, R r) { return std::move(r += v); }

我的回答是在我没有意识到这种实现时写的:

R operator+=(R&& r, const V& v)
R operator+=(R&& r, V&& v)

考虑到这些功能,Yakk的答案会更好。

答案 1 :(得分:1)

假设:

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); }

我们应该:

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); } 

我认为R移动成本低,而带有+=的{​​{1}}只比V&&稍微高效。

请注意,V const&的返回值应为值。我用R operator+=( R&& r, ? )来实现它,然后进入返回值。

这意味着您必须在上述样板之外实现两个+=(const&,?)运算符。

如果我们获得的移动+=没有收益:

V

3样板,一个实际实现的功能。

如果您不喜欢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; } ,我们可以将其重写为:

R operator+=( R&& r, const V& v)

并且如果需要,同样适用于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); } 个案例:

V&&

我们在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)); } 的签名中复制R而不是在内部;如果我们打算复制它,也可以在签名中进行复制。

Want speed? Pass by value.是用于将operator+R const&重载删除为冗余的技术。