Hi I was wondering how I could tackle this problem,
I need to overload +, - and * operators but need to replace them with Logical operators for example;
"+" should use OR
0+0 = 0 , 0+1 = 1, 1+1 = 1 ,1+0 = 1
would i have to place in the overload some sort of if statment?
Any help on how i could do this?
Thanks
They will being using binary as the data type, two matrices with binary as their data
There's no need for an if statement, you just need to return the result of && and ||.
struct A
{
bool val;
bool operator + (const A& other) { return val || other.val; }
bool operator * (const A& other) { return val && other.val; }
};
Note that you can't overload operators for built-in types. At least one of the arguments must be user-defined.
You don't want to overload those operators for integers, or any other built-in types, do you? Because it's impossible. If you have your own class which contains a boolean or integer value then the logic goes something like this:
bool operator + (const MyClass& m1, const MyClass& m2)
{
return m1.GetMyBooleanMember() || m2.GetMyBooleanMember();
}
Overloading operator+(int, int) is not possible, however you can create a new type that wraps an int and has the behavior you want...
struct BoolInt
{
int i;
};
BoolInt operator+(BoolInt x, BoolInt y) { return { x.i || y.i }; }
BoolInt operator*(BoolInt x, BoolInt y) { return { x.i && y.i }; }
BoolInt operator-(BoolInt x, BoolInt y) { return { x.i || !y.i }; } // guessing
Related
In the code, why is (10 != i) calling == instead of !=? The other two call !=
#include <iostream>
class Integer
{
int x;
public:
bool
operator== (const Integer &i)
{
std::cout << "==";
return x == i.x;
}
bool
operator!= (const Integer &i)
{
std::cout << "!=";
return x != i.x;
}
Integer (int t = 0) { x = t; }
};
int
main ()
{
Integer i;
std::cout << (i != i) << '\n'; // calls !=
std::cout << (i != 100) << '\n'; // calls !=
std::cout << (10 != i) << '\n'; // calls ==
}
Prior to C++20, you'd need to add two free functions for the comparison where the int is on the left-hand side:
bool operator==(int lhs, const Integer& rhs) {
return rhs == lhs;
}
bool operator!=(int lhs, const Integer& rhs) {
return rhs != lhs;
}
You should also make the member comparison operators const qualified:
class Integer {
public:
//...
bool operator==(const Integer &i) const { // note const
std::cout << "==";
return x == i.x;
}
bool operator!=(const Integer &i) const { // note const
std::cout << "!=";
return x != i.x;
}
//...
};
You could also remove the member operators to simplify things. Now the left-hand side int will be implicitly converted to Integer and then compared with the right-hand side:
class Integer {
int x;
public:
Integer(int t = 0) : x{t} {}
friend bool operator==(const Integer& lhs, const Integer& rhs) {
return rhs.x == lhs.x;
}
friend bool operator!=(const Integer& lhs, const Integer& rhs) {
return !(rhs == lhs);
}
};
Since you've tagged this C++20, you can let operator== do all the work. See Default comparisons. It'll be used for operator!= too.
class Integer {
int x;
public:
bool operator==(const Integer &i) const {
std::cout << "==";
return x == i.x;
}
Integer(int t = 0) : x{t} {}
};
... and it'll correctly show that it used operator== for all your != comparisons (and negated it).
More from Defaulted equality comparison:
A class can define operator== as defaulted, with a return value of bool. This will generate an equality comparison of each base class and member subobject, in their declaration order. Two objects are equal if the values of their base classes and members are equal. The test will short-circuit if an inequality is found in members or base classes earlier in declaration order.
Per the rules for operator==, this will also allow inequality testing
This means that you will in fact get away with the below only since C++20:
class Integer {
int x;
public:
bool operator==(const Integer &i) const = default;
Integer(int t = 0) : x{t} {}
};
or even better, get all the comparison operators for free by defaulting the spaceship operator <=>:
class Integer {
int x;
public:
auto operator<=>(const Integer &i) const = default;
Integer(int t = 0) : x{t} {}
};
There are two new additions to C++20 that made this possible (note that your code doesn't compile in earlier standard versions).
Compiler will attempt to replace a != b with !(a == b) if there is no suitable != for these arguments.
If there is no suitable a == b, compiler will attempt b == a as well.
So, what happens - compiler first notices that it doesn't know how to compare 10 != i, so it tries !(10 == i). There is still no suitable comparison, so it tries !(i == 10) and it can finally be done using your implicit constructor to convert 10 to Integer.
It can be easily verified by adding more info to debug print:
bool
operator== (const Integer &i) const
{
std::cout << x << "==" << i.x << ' ';
return x == i.x;
}
will print 0==10 1 in the last line (see it online).
As noticed in comments, you don't even need operator !=, due to aforementioned behaviour C++20 compiler will automatically convert any such call to operator ==.
I'm writing a game in C++ for my Arduino and I've recently found the joys of operator overloading in structs. So far so good! I'm now stuck on the syntax to overload operators on properties. I want to implement something like this so that if my x or y values increase over the screen width I wrap the value back to 0. Many thanks!
// My guess :(
x& operator++(x &newx, int){
if (x == SCREEN_WIDTH - 1)
return 0;
else
return x + 1;
}
My struct definition is:
struct point_t
{
uint8_t x;
uint8_t y;
x& operator++(x &newx, int){
if (x == SCREEN_WIDTH - 1)
return 0;
else
return x + 1;
}
point_t& operator=(const point_t &p)
{
x = p.x;
y = p.y;
return *this;
}
bool operator==(const point_t &p) const
{
return (x == p.x && y == p.y);
}
bool operator!=(const point_t &p) const
{
return !(x == p.x && y == p.y);
}
};
You can't do this exactly as written. The return type of operator should be type.
What you can do is to create a new type, say coordinate, overload operator++ for it, and have your x (and y) have coordinate type, not uint8_t.
Possible solution (based on code by #MrMase):
template<uint8_t MAX>
class coordinate_t
{
private:
int8_t _p;
public:
coordinate_t(int8_t p = 0): _p(p) {}
// Postfix ++
coordinate_t operator++(int)
{
coordinate_t p(_p);
++_p;
if (_p > MAX - 1)
_p = 0;
return p;
}
// Postfix --
coordinate_t operator--(int)
{
coordinate_t p(_p);
--_p;
if (_p < 0)
_p = MAX - 1;
return p;
}
int get() const {return _p;}
};
typedef coordinate_t<SCREEN_WIDTH> xcoordinate_t;
typedef coordinate_t<SCREEN_HEIGHT> ycoordinate_t;
I've made it a template to allow for a simple typedef to define different coordinates; you might also have made MAX a private field and subclass it for different coordinates. In fact, it seems that the template solution is more safe, as it will not allow you to mix different coordinates; however, you might want to reconsider this based on your actual usage.
See full example: http://coliru.stacked-crooked.com/a/5a34261310d05a54
When overloading unary operators (operators with only a single operand, like the increase/decrease operators ++ and --) as member functions, they don't have an argument since they are performed on this. The exceptions being the dummy int arguments for the postfix increase/decrease operators.
The returned value differs depending on which operator you overload, but generally for unary operator you return a reference to object, i.e. *this.
Example
struct point_t
{
int x;
// Prefix increase operator
point_t& operator++()
{
++x;
return *this;
}
// Postfix increase operator
point_t operator++(int)
{
point_t old(*this); // Create new object using copy-constructor
operator++(); // Call prefix operator++ on `this`
return old; // Return old value, before increment
}
...
};
It's all documented in this operator overloading reference, as well as plenty of tutorials all over the Internet.
On an unrelated note, that operator!= can be implemented by using the == operator that you have already implemented:
bool operator!=(const point_t& p) const
{
return !(*this == p);
}
It's always a good idea to use existing operators when creating related operator overloads.
It seems it's not possible to overload a property of an enum so I'm going to do the next best thing: create a new type called xcordinate and overload the ++operator
Thanks very much to everyone who helped. I'm grateful! :)
Here is a snippet of the code that I found on my beginner file:
struct TriIndex //triangle index?
{
int vertex; //vertex
int normal; //normal vecotr
int tcoord; //
bool operator<( const TriIndex& rhs ) const {
if ( vertex == rhs.vertex ) {
if ( normal == rhs.normal ) {
return tcoord < rhs.tcoord;
} else {
return normal < rhs.normal;
}
} else {
return vertex < rhs.vertex;
}
}
};
I've never seen a bool operator inside a struct before. Can anyone explain this to me?
TL;DR: The code inside the function is evaluating if *this is < rhs, bool is merely the return type.
The operator is operator < which is the less than operator. The current object is considered the left hand side or lhs, and the object compared against, the right hand of the a < b expression is rhs.
bool // return type
operator < // the operator
(const TriIndex& rhs) // the parameter
{
...
}
It returns true if the current object is less than (should preceed in containers, etc) the object after the < in an expression like:
if (a < b)
which expands to
if ( a.operator<(b) )
There is a bool operator:
operator bool () const { ... }
which is expected to determine whether the object should evaluate as true:
struct MaybeEven {
int _i;
MaybeEven(int i_) : _i(i_) {}
operator bool () const { return (_i & 1) == 0; }
};
int main() {
MaybeEven first(3), second(4);
if (first) // if ( first.operator bool() )
std::cout << "first is even\n";
if (second) // if ( second.operator bool() )
std::cout << "second is even\n";
}
bool operator<( const TriIndex& rhs )
This line of code is defining a comparison of user-defined datatypes. Here bool is the type of the value this definition will return i.e. true or false.
const TriIndex& rhs
This code is telling the compiler to use struct object as a parameter.
if ( vertex == rhs.vertex ) {
if ( normal == rhs.normal ) {
return tcoord < rhs.tcoord;
} else {
return normal < rhs.normal;
}
} else {
return vertex < rhs.vertex;
}
The above code is defining criteria of the comparison i.e. how the compiler should compare the two when you say struct a < struct b . This is also called Comparison Operator Overloading.
TL-DR;
So after defining the operator when you write a code say:
if (a < b) {
.......
}
where a and b are of type struct fam. Then the compiler will do the if else operations inside the definition and use the return value . If return = true then (a < b) is true otherwise the condition will be false.
That code allows you to compare different TriIndexes with the < operator:
TriIndex alpha;
TriIndex beta;
if (alpha < beta) {
etc;
}
bool operator<( const TriIndex& rhs ) is the "less than" operating (<), bool is the return type of the "less than" operator.
C++ allows you to override operators such as < for structs and classes. For example:
struct MyStruct a, b;
// assign some values to members of a and b
if(a < b) {
// Do something
}
What does this code do? Well it depends on how the "less than" operator has been defined for MyStruct. Basically, when you do a < b it will call the "less than" operator for that struct with b being rhs (right hand side) or whatever you call the first parameter, although rhs is the typical convention.
I am trying to find a simple example program that overloads the following operators of a mathematic vector.
Constructor // create
= (equals) // assign
+; -; +=; -= // add sub
*; /; *=; /= // multi divide
++; -- // plus minus
== // compare
>; >=
<; <=
[] // access a value
Cant seem to find any good simple tutorials. I emphasize the simple because I am only learning this stuff now. If someone could link me or even better program a simple overload for just one of the operators as an example would be incredible!
There are a few things to know when you write operators, which are not as often used with other functions.
The assign operators, for example, will return *this because you change the value of the vector:
class v {
public:
double x_, y_;
v& operator += (const v& rhs)
{
_x += rhs._x;
_y += rhs._y;
return *this;
}
};
Another interesting one, the pre ++ and post ++ are different only because of an unused parameter:
class v {
public:
double x_, y_;
v& operator ++ (); // ++v
v& operator ++ (int); // v++
};
The "equal" (assignment) is another one that is tricky when you use pointers. For a vector, it generally won't be a problem, but if you define a vector V and assign it to itself, you have to be careful:
class v {
public:
double x_, y_;
v& operator = (const v& rhs)
{
if(this != &rhs)
{
x_ = rhs.x_;
y_ = rhs.y_;
}
return *this;
}
};
In your case, the if() will most certainly not be useful, but think about doing something like this:
delete p_;
p_ = new foo;
p_->x_ = rhs.p_->x_;
If &rhs == this, then the delete p_ deleted the rhs pointer! That means accessing it on the 3rd line is a bug.
The rest should be easy enough to work with. The compare operators return bool and are const:
class v {
public:
double x_, y_;
bool operator == (const v& rhs) const
{
return x_ == rhs.x_ && y_ == rhs.y_;
}
};
Although, since C++20, you are expected to only declare the three way comparison operator <=> which allows the compiler to implement all the other comparison operators for you. This one returns a negative number (smaller: a < b), 0 (equal: a == b), or a positive number (larger: a > b).
I'm not sure what makes a vector bigger or smaller, I used the length from (0, 0) in this example:
class v {
public:
double x_, y_;
int operator <=> (const v& rhs) const
{
if(x_ == rhs.x_ && y_ == rhs.y_)
{
return 0;
}
return length() > rhs.length() ? 1 : -1;
}
};
Except for the [] operator. There are two versions of that one:
class v {
public:
// I would imagine you'd use an array but as a simple example...
double x_, y_;
double operator [] (int idx) const
{
return idx == 0 ? x_ : y_;
}
v_ref operator [] (int idx)
{
v_ref v(this, idx);
return v;
}
};
As you can see, the non-constant version of the [] operator returns a reference. This is necessary so you can write something like:
r[3] = 7.3;
r[3] returns that reference, then the assignment of the reference is called with 7.3 as the parameter. (Note that we should probably throw an error if you use 3 as the index when you only have 2 values: 0 and 1--this is not shown here)
class v_ref
{
public:
v *p_;
int i_;
v_ref(v *p, int i)
: p_(p), i_(i)
{
}
operator = (double q)
{
// again, I suppose you'd use an array instead!
if(i_ == 0)
{
p_->x_ = q;
}
else
{
p_->y_ = q;
}
}
};
Assuming you want some security, the vector pointer could make use of a reference counter so you know whether a main vector object gets deleted before all of its reference objects...
Another note: I would imagine that your constructor will allocate an array of double (or use an std::vector<double> type...) If you use new, remember to delete in the destructor and that's when the if() in the assignment operator is very important.
I have such code
class Number
{
int m_value;
public :
Number(const int value) :
m_value(value)
{
}
operator const int() const
{
return m_value;
}
int GetValue() const
{
return m_value;
}
};
bool operator==(const Number& left, const Number& right)
{
return left.GetValue() == right.GetValue();
}
class Integer
{
int m_value;
public :
Integer(const int value) :
m_value(value)
{
}
operator const int() const
{
return m_value;
}
bool operator==(const Integer& right) const
{
return m_value == right.m_value;
}
bool operator==(const int right) const
{
return m_value == right;
}
int GetValue() const
{
return m_value;
}
};
bool operator==(const int left, const Integer& right)
{
return left == right.GetValue();
}
int main()
{
Number n1 = 1;
Number n2 = 1;
int x3 = 1;
n1 == n2;
n1 == x3; // error C2666: 'operator ==' : 3 overloads have similar conversions
x3 == n1; // error C2666: 'operator ==' : 2 overloads have similar conversions
Integer i4 = 1;
Integer i5 = 1;
i4 == i5;
i4 == x3;
x3 == i4;
return 0;
}
For class Number I have two errors as shown in the code above. For class Integer everything is OK. The problem is, I want to keep in resulting class single-parameter constructor, cast operator and equality operations (MyClass == int, int == MyClass, MyClass == MyClass), but I want to implement only one version of operator== as in class Number. I don't see any way to do this. Is that even possible or I must have all three implementations as in class Integer? I know why I get these errors I just don't like the solution I have.
In class Number you define a conversion operator to int and your constructor allows converting an int to a Number. Therefore, when comparing a Number n and an int x for equality, ambiguity arises: should the compiler invoke the built-in operator == for ints and convert n to an int, or should it rather pick your operator and convert x to a Number? Both conversions are equally good, and it can't choose one.
So yes you have to define three versions, or add a template operator which can perfectly match the type of all arguments and forward to your operator explicitly, like this one (but you most likely want to guard it with some enable_if to limit its applicability only to the appropriate T and U):
template<typename T, typename U> // beware: this will match anything. to be constrained
bool operator == (T n, U const& u)
{
return (Number(n) == Number(u));
}
You can define only one operator== as member function:
bool operator==(const int& right) const
{
std::cout << "custom\n";
return this->GetValue() == right;
}
Then,
n1==n2: n2 will be converted to int and custom operator will be used.
n1 == n3: custom operator will be used
n3==n1: built-in operator will be used
Note, that you want your operator== be const to be able to compare constant Numbers
In C++11 you can make operator int explicit.
Another approach would be to use SFINAE to have a template == that works for one or more Number args, but that is using a bazooka to kill an ant.