C++ 如何使用移动语义重载一元算术
我想为std::vector实现一元算术运算符和移动语义。这样做的目的是避免在运算符内部进行内部分配(如果它应用于右值) 问题:以下操作未编译:c=-(a+b) 这不会编译的原因是,为std::vector实现的二进制算术运算符+I返回一个常量左值(因此编译器会抱怨(a+b)=c,这没有意义) 二进制+运算符C++ 如何使用移动语义重载一元算术,c++,operator-overloading,C++,Operator Overloading,我想为std::vector实现一元算术运算符和移动语义。这样做的目的是避免在运算符内部进行内部分配(如果它应用于右值) 问题:以下操作未编译:c=-(a+b) 这不会编译的原因是,为std::vector实现的二进制算术运算符+I返回一个常量左值(因此编译器会抱怨(a+b)=c,这没有意义) 二进制+运算符 template<class T, class AllocVect1, class AllocVect2> inline const std::vector<T>
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;
}
模板
内联常量std::向量运算符+(
常数标准::向量和v1,
const std::vector和v2){
std::向量vout;
*计算vout=v1+v2*
退票;
}
一元运算符
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;
}
模板
内联常量std::vector和运算符-(std::vector和&v){
std::transform(
v、 begin(),
v、 结束(),
v、 begin(),
[](const auto&val){return-val;});
返回v;
}
通过值传递并返回向量。
当你考虑这些事情时,听起来有点不合常理:
std::move
const
限定符模板
std::vector操作符-(std::vector v){//1。
std::for_each(//2。
v、 begin(),
v、 end(),
[](T&val){val=-val;});
返回v;//3。
}
可以使用右值(移动+修改+移动)和左值(复制+修改+移动)调用此运算符
也就是说,const-Param&
和Param&&
单独重载有其优点,其细节已在单独的答案中解释:
std::move
const
限定符模板
std::vector操作符-(std::vector v){//1。
std::for_each(//2。
v、 begin(),
v、 end(),
[](T&val){val=-val;});
返回v;//3。
}
可以使用右值(移动+修改+移动)和左值(复制+修改+移动)调用此运算符
也就是说,const-Param&
和Param&&
单独重载有其优点,其细节已在单独的答案中解释:
const
引用?请提供一个适当的。您建议的运算符具有令人困惑/惊讶的语义。为什么它返回一个const
引用?感谢您的详细解释!然而,我想知道在下面的作业中会发生什么:autoc=-(a+b);?运算符+返回一个常量左值,这样程序员就不会被引诱去编写类似于:(a+b)=‘其他向量’的东西。但是,由于这个操作符+返回一个常量左值,它会在调用操作符时复制或移动吗?你在回答中写道:(a+b)=‘其他向量’
——这真的是一个值得保护的用例吗?您多长时间见过这样的代码?如果您还将运算符+
修改为按值返回而不是常量左值,那么一切都将正常工作--您不能分配给未命名的临时值(因此(a+b)=
。是不允许的),并且-(a+b)
将“正常工作”,而无需额外的副本。对于基本类型(a+b)='something'发出编译器错误:赋值的左操作数需要左值。如果有类似的通用类定义了操作符的重载,那该多好啊!谢谢您的详细解释!然而,我想知道在下面的作业中会发生什么:autoc=-(a+b);?运算符+返回一个常量左值,这样程序员就不会被引诱去编写类似于:(a+b)=‘其他向量’的东西。但是,由于这个操作符+返回一个常量左值,它会在调用操作符时复制或移动吗?你在回答中写道:(a+b)=‘其他向量’
——这真的是一个值得保护的用例吗?您多长时间见过这样的代码?如果您还将运算符+
修改为按值返回而不是常量左值,那么一切都将正常工作--您不能分配给未命名的临时值(因此(a+b)=
。是不允许的),并且-(a+b)
将“正常工作”,而无需额外的副本。对于基本类型(a+b)='something'发出编译器错误:赋值的左操作数需要左值。如果对具有定义的运算符重载的一般类也有类似的情况就好了+