我正在尝试写我的vec课程。为了提高效率,我使用移动语义。
Vec<int> v1;
Vec<int> v2;
Vec<int> v3;
Vec<int> v4;
v4 = v1 + v2; // Line 1
v4 = v1 + v2 + v3; // Line 2
v4 = v1 + (v2 + v3); // Line 3
但是,为了让上面的每一行只调用一次复制构造函数,我必须用一个运算符重载四个函数。像下面的代码一样。
Vec(Myself&& v)
{ // move consturctor
dim = v.dim;
value = std::move(v.value);
}
Myself& operator+= (const Myself& v)
{
for (size_type i = 0; i < dim; ++i) (*this)[i] += v[i];
return *this;
}
template<typename std::enable_if<!std::is_reference<Myself>::value>::type* = nullptr> // SFINAE
friend Myself& operator+ (Myself&& a, const Myself& b)
{
return a += b;
}
Myself& operator+ (Myself&& v) const
{
return v += *this;
}
Myself operator+ (const Myself& v) const
{
Myself ansV(*this);
ansV += v;
return ansV;
}
感谢轨道中的轻盈竞赛提醒。我将移动构造函数添加到上面的代码中。
1。有没有办法为一个操作员编写较少的函数?
2。为什么在函数friend Myself& operator+ (Myself&& a, const Myself& b)
添加SFINAE,而不是Myself& operator+ (Myself&& v) const
?它用于修复v4 = v1 + (v2 + v3);
。
答案 0 :(得分:2)
当我为算术类T
编写运算符时,我通常会执行以下操作:
(a)如果操作是可交换的(a + b等于b + a):
将+=
的实现放入T:
T & T::operator+=(T const& other) {
// [Perform the actual operation (add other to *this)]
x += other.x; // or something similar
return *this;
}
在课堂外提供以下两个功能:
T operator+(T a, T const& b) {
a += b;
return a;
}
T operator+(T const& a, T && b) {
MyInt temp(std::move(b));
temp += a;
return temp;
}
(b)如果操作不可交换(a-b与b-a不同):
将-=
的实现放入T并提供第二个函数,该函数对第二个操作数而不是第一个操作数起作用:
T & T::operator-=(T const& other) {
// [Perform the actual operation of (subtract other from *this)]
x -= other.x; // or something similar
return *this;
}
void T::operatorMinus(T & other) const {
// [Perform the actual operation, but work on other instead of *this]
other.x = x - other.x; // or something similar
}
在课堂外提供以下两个功能:
T operator-(T a, T const& b) {
a -= b;
return a;
}
T operator-(T const& a, T && b) {
MyInt temp(std::move(b));
a.operatorMinus(temp);
return temp;
}
<强>结果:强>
以下示例中的gcc和clang现在只需要使用-O3
(operator-
相同)中的单个复制构造函数:
T a1, a2, a3, x;
x = a1 + a2;
x = a1 + a2 + a3;
x = (a1 + a2) + a3;
x = a1 + (a2 + a3);
即使两个操作数都是rvalues的情况也是在没有歧义的情况下处理的。以下编译正常,即使需要两份副本(a1+a2
一份和a3+a4
一份):
T a1, a2, a3, a4, x;
x = (a1 + a2) + (a3 + a4);