Let me give the example:
Code: Select all
struct Vec2f
{
Vec2f& operator+=(const Vec2f& other)
{
x += other.x;
y += other.y;
return *this;
}
Vec2 operator+(const Vec2f& other)const
{
return Vec2f(*this) += other;
}
float x,y;
};
I believe the reason for this is to reduce the amount of duplicated code, but why isn't it the other way round, the operator+= defined in terms of operator+. Well, I believe it's because standard practice is to define non-assignment operators as free standing functions and friending those functions.
Code: Select all
struct Vec2f
{
Vec2f& operator+=(const Vec2f& other)
{
x += other.x;
y += other.y;
return *this;
}
friend Vec2 operator+(const Vec2f& leftSize, const Vec2f& rightSide);
float x,y;
};
Vec2 operator+(const Vec2f& leftSize, const Vec2f& rightSide)
{
return Vec2f(*leftSide) += rightSide;
}
Now, what if we wanted to implement constexpr which would allow us to have a compile time vector.
Code: Select all
struct Vec2f
{
constexpr Vec2f()=default;
// Can't declare constexpr for this function, it changes the state of the object
Vec2f& operator+=(const Vec2f& other)
{
x += other.x;
y += other.y;
return *this;
}
// This is illegal because constexpr functions can only call other constexpr functions
constexpr Vec2 operator+(const Vec2f& other)const
{
return Vec2f(*this) += other;
}
float x = 0.f,y = 0.f;
};
Code: Select all
struct Vec2f
{
constexpr Vec2f()=default;
// Still can't declare constexpr, but won't need to if you are wanting to change the state
// of this object during runtime.
Vec2f& operator+=(const Vec2f& other)
{
*this = *this + other;
return *this;
}
// This is legal because we aren't calling a non-constexpr function and it's even legal C++11
// code because it doesn't have any newly declared variables or multiple return or code paths.
constexpr Vec2 operator+(const Vec2f& other)const
{
return { x + other.x, y + other.y };
}
float x = 0.f,y = 0.f;
};
Code: Select all
struct Vec2f
{
Vec2f& operator+=(const Vec2f& other)
{
*this = *this + other;
return *this;
}
friend constexpr Vec2 operator+(const Vec2f& leftSize, const Vec2f& rightSide);
float x,y;
};
constexpr Vec2 operator+(const Vec2f& leftSide, const Vec2f& rightSide)
{
return {leftSide.x + rightSide.x, leftSide.y + rightSide.y};
}