I have simply declared a structure like this -
struct data{
int x,y;
};
Now I have declared 2 variables a
& b
of data
type. I've assigned appropriate values to them. Now, I want to check if they are equal! I am trying to do like this -
data a,b;
a.x=12, a.y=24;
b.x=15, b.y=30;
if(a!=b)cout<<"a~b"<<endl;
But the compiler is giving me the following error on the 4th
line ->
error: no match for 'operator!=' (operand types are 'data' and 'data')
Where is the problem actually? Isn't this compare supported in C++?? Or I'm making any mistakes??
What is the exact and easiest way to do this?? Do I need to compare each of the elements in the structure separately?? Or there's any other smarter way??
C provides no language facilities to do this - you have to do it yourself and compare each structure member by member.
Because the operator == is not aware of all the members of the structure it would need to compare, you are! You can't compare strings either, in C - at least, not with '==' or equivalent.
Yeah. It is relational operator. Relational operators are only used to compare two or more things.
C++ gives you attribute-by-attribute assignment implicitly, but no comparison for equality or ordering. The reason is "just because", don't look too hard into philosophy.
You must to provide those operators, if needed, by implementing them yourself explicitly, for example:
bool operator<(const Data& other) const {
if (x < other.x) return true;
if (x > other.x) return false;
return y < other.y;
}
bool operator==(const Data& other) const {
return x == other.x && y == other.y;
}
and so on.
Note also that defining for example ==
doesn't give you !=
automatically and defining <
doesn't provide >=
implicitly.
C++20 introduces (will introduce) a new operator <=>
(friendly name "spaceship operator") exactly to remove the verbosity of having to define all possible relational operators. In this case adding:
std::strong_ordering operator<=>(const Data& other) const {
if (auto cmp = x <=> other.x; cmp != 0) return cmp;
return y <=> other.y;
}
will allow compilation of all relational tests (<
, <=
, >
, >=
, ==
, !=
) between elements of the class based on checking x
first and, if that check doesn't resolve, checking y
instead.
You have to implement all operators explicitely that you intent to use. In your case, you will need to supply bool operator!=(const data&, const data&)
.
A nice way to implement it for PODs like this is to use std::tuple
since it already implements ordering:
#include <tuple>
// ...
bool operator!=(const data& p_lhs, const data& p_rhs)
{
return std::tie(p_lhs.x, p_lhs.y) != std::tie(p_rhs.x, p_rhs.y);
}
std::tie
(documentation) creates a temporary tuple of references. Those two tuples can then be compared, since std::tuple
defines all comparison operators, as shown here.
I chose to implement operator!=
as a free function. You can, of course, choose to implement it as member of your class:
struct data
{
bool operator!=(const data& p_rhs) const
{
return std::tie(x, y) != std::tie(p_rhs.x, p_rhs.y);
}
int x, y;
};
Of course you should define all other operators, too. Remember that you can implement most operators by delegating to others.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With