ihe*_*eap 6 c++ move operator-overloading c++11
我想知道在重载operator +和/或operator + =时使用移动语义是什么样的情况.即使在这个问题中解释了如何做到这一点,我也无法理解为什么要这样做.我们考虑运算符+ =.如果我只是通过引用右侧传递并在左侧对象上进行适当的更改,则无论如何都没有不必要的副本.所以我们回到同一点:在这种情况下移动语义是否有益?
Mat*_* M. 12
是的,不是.
操作者+ =
移动语义通常不一定有用operator+=
,因为您已经在修改左侧的参数(this
),因此您已经拥有了大部分时间都可以使用的资源.
不过,作为优化,它可能是值得的.想象一个std::string
默认构造函数不分配任何内存的实现.然后std::string::operator+=(std::string&&)
可以简单地从RHS窃取资源.或者想象一下,RHS缓冲区大到可以容纳除了LHS之外的所有东西,然后如果你可以使用RHS缓冲区你就是黄金:只需交换和前置.
所以,它可能是值得的,但你必须研究它.因此:
T& T::operator+=(T const&)
:永远在场T& T::operator+=(T&&)
:在有意义时启用移动语义运营商+
在这里它总是有用的(假设我们正在讨论移动语义有用的类).
问题是,operator+
产生一个临时的(突然出现)所以它通常必须为这个临时创建资源.然而,如果它可以窃取它们而不是创造它们,那肯定会更便宜.
但是,您无需提供所有重载:
T operator+(T const&, T const&)
T operator+(T&&, T const&)
T operator+(T const&, T&&)
T operator+(T&&, T&&)
(消除歧义所需)不,您可以重用operator=
在函数签名中使用和创建临时权限的相同技巧(通过复制一个参数).如果类型是可移动的,则移动构造函数将被调用,否则它将是复制构造函数,但是因为您无论如何都需要临时,不会损失性能.
inline T operator+(T left, T const& right) { left += right; return left; }
inline T operator+(T const& left, T right) { right += left; return right; } // commutative
inline T operator+(T left, T&& right) { left += right; return left; } // disambiguation
Run Code Online (Sandbox Code Playgroud)
没有太大的收获(3而不是4)但是,我会尽我所能!
当然,对于字符串,operator+
不是可交换的(这就是为什么它是一个坏的重载),所以第二次重载的实际实现需要一个prepend
方法.
编辑:跟随移动语义和运算符重载似乎我有点过于热情.从Ben Voigt的回答中窃取,我们得到:
inline T operator+(T left, T const& right) { left += right; return left; }
inline T operator+(const T& left, T&& right) { right += left; return right; }
Run Code Online (Sandbox Code Playgroud)
另一方面,这似乎只适用于交换操作; -
不工作的方式,但可能可以进行调整,/
并%
在另一方面...