我想用std :: vector的移动语义实现一元算术运算符。目的是避免将运算符内部应用到右值时对其进行内部分配。
问题:以下操作无法编译:c =-(a + b)
之所以无法编译,是因为我为std :: vector实现的二进制算术运算符+我返回了const lvalue(这样编译器将抱怨(a + b)= c,这没有意义)
二进制+运算符
template<class T, class AllocVect1, class AllocVect2>
inline const std::vector<T> operator+ (
const std::vector<T, AllocVect1> &v1,
const std::vector<T, AllocVect2> &v2) {
std::vector<T> vout;
*Compute vout = v1 + v2*
return vout;
}
一元运算符
template<class T, class Alloc>
inline const std::vector<T>& operator- (std::vector<T, Alloc> &&v) {
std::transform (
v.begin (),
v.end (),
v.begin (),
[](const auto &val){return -val;});
return v;
}
答案 0 :(得分:0)
通过值传递并返回向量。
听起来似乎不合常理,一旦您考虑了以下因素,便会变得有意义:
可以将临时对象隐式地移动到一个值参数中-不发生复制。这就像您要在局部变量上调用std::move
。
由于该对象(参数)没有const
限定符,因此可以就地修改。
可以返回修改后的对象,并再次隐式应用移动语义。永远不要返回对局部变量的引用-左值引用或右值引用都不能。
template<class T>
std::vector<T> operator-(std::vector<T> v) { // 1.
std::for_each( // 2.
v.begin(),
v.end(),
[](T& val) {val = -val;});
return v; // 3.
}
可以同时使用rvalues(移动+修改+移动)和lvalues(复制+修改+移动)来调用此运算符。
话虽这么说,const Param&
和Param&&
的单独重载有 的优点,其详细信息已在单独的答案中进行了解释: