overloading an operator, why?

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
lysear
Posts: 3
Joined: March 31st, 2020, 4:22 pm

overloading an operator, why?

Post by lysear » March 31st, 2020, 4:25 pm

I have been going through the lessons now for a few months, I am doing pretty good, still not brilliant with when to use const / static constexpr, not too great with pass by reference, which has become apparent through the snek game, which has a tonne of that.

The main question I have is, what is the benefit/need of reassigning the meaning of a simple operator, like "=" or "+" in a function. Am I just misunderstanding, because it appears to be what you are doing,

thanks for your time, these classes are awesome


Regards,


Lysear

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: overloading an operator, why?

Post by albinopapa » March 31st, 2020, 5:48 pm

Take your pick:

Code: Select all

struct Vec2
{
     float x, y;
};

Vec2 operator+(Vec2 const& a, Vec2 const& b )
{
     return { a.x + b.x, a.y + b.y };
}

Vec2 add(Vec2 const& a, Vec2 const& b )
{
     return { a.x + b.x, a.y + b.y };
}

auto a = { 32.f, 3.14f };
auto b = { 37.f, 1.06f };

Choose:
auto c = a + b;

or 

auto c = add( a, b );
Most people would prefer the operator+ overload for simplicity and understanding.

The only times you need to overload the operator= is for conversion assignments or if you have to do something special when copying or moving one user-defined class object to another. For instance, in the intermediate series chili has a Surface class that has 'int width, height' members. When you move one Surface object to another, the width and height are copied, but the original object's width and height aren't set to 0 to signify that the object isn't valid anymore. To correct this, he creates a custom move assignment operator ( operator= ) so that those member variables can be set to 0.

Say you wanted to do something like:

Code: Select all

std::string s = 42;
Obviously you can't with the standard string, but with a custom wrapper you could.

Code: Select all

#pragma once

#include <string>

class String
{
public:
	String() = default;
	template<
		typename T,
		std::enable_if_t<!std::is_arithmetic_v<T>, int> = 0
	> String( T&& str_ ) :str( std::forward<T>( str_ ) ) {}

	template<
		typename T,
		std::enable_if_t<std::is_arithmetic_v<T>, int> = 0
	> String( T val ) :str( std::to_string( val ) ) {}
	
	template<
		typename T, 
		std::enable_if_t<std::is_arithmetic_v<T>, int> = 0
	> String& operator=( T val ) { str = std::to_string( val ); return *this; }

	template<
		typename T,
		std::enable_if_t<std::is_arithmetic_v<T>, int> = 0
	> String operator+( T val )const
	{
		return str + std::to_string( val );
	}

	template<
		typename T,
		std::enable_if_t<!std::is_arithmetic_v<T>, int> = 0
	> String operator+( T&& str_ )const
	{
		return str + str_;
	}
private:
	std::string str;
};

// User-defined literal
String operator""_string( char const* str, std::size_t len )
{
	return { str };
}

Usage

Code: Select all

std::string func()
{
	auto str = "Life: "_string + 42 + "\nShield: " + 0.f;
}
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
chili
Site Admin
Posts: 3948
Joined: December 31st, 2011, 4:53 pm
Location: Japan
Contact:

Re: overloading an operator, why?

Post by chili » April 3rd, 2020, 2:04 am

What, you mean you don't prefer this?

Code: Select all

add( multiply( a,b ),divide( c,subtract( d,e ) ) )
Chili

Post Reply