Can't use Operator != for bool - c++

I made operator for !=
PairXY operator != (PairXY a, PairXY b) {
PairXY res(a.x != b.x, a.y != b.y);
return res;
}
And i want to use it in this loop:
while (l.b!=l.a){}
But it gives me this error: could not convert 'operator!=(l.Line::b, l.Line::a)' to 'bool', i tried changing operator's PairXY to bool, but it stil didn't help.

bool operator != (PairXY a, PairXY b) { ... }

The return type should be bool:
bool operator != (const PairXY & a, const PairXY & b);
Also, better make the parameters const reference, as I shown above.

Do you want to return a pair of (probably) numbers, or a single boolean?
Usually, tuple-s are different (mathematically) when any component is pairwise different. So I would code something like
bool operator != (PairXY a, PairXY b) { return a.x != b.x || a.y != b.y; }
but perhaps you want something else (but then, I won't call that !=).

Probably this is how your code should be.
class PairXY {
public:
PairXY( int _x, int _y): x(_x),y(_y){}
bool operator != (const PairXY a) {
return(this->x != a.x && this->y != a.y);
}
private:
int x;
int y;
};
int main ( int argc, char** argv ) {
return 0;
}

Related

comparing == operator for (struct &a, struct &b) vs (const struct &a, const struct &b)

I have defined a struct class called Point in my header file as follows -
namespace global_planner {
class GlobalPlanner : public nav_core::BaseGlobalPlanner {
struct Point {
__uint32_t x, y;
bool operator==(const Point &p1 ) {
return ((p1.x == x) && (p1.y == y));
}
bool operator<(const Point &p1 ) const {
return ((p1.x < x) || (p1.x == x && p1.y < y) ) ;
}
};
public:
///
private:
////
};
};
In my source file (named global_planner.cpp), I have a function named generate_straight_path defined as follows -
bool GlobalPlanner::generate_straight_path(const Point &p1, const Point &p2){
if(costmap_ros_->getCost(p1.x, p1.y) == costmap_2d::LETHAL_OBSTACLE) {
cout << "Point p1 is on obstacle!" << endl;
return false;
}
if(costmap_ros_->getCost(p2.x, p2.y) == costmap_2d::LETHAL_OBSTACLE) {
cout << "Point p2 is on obstacle!" << endl;
return false;
}
if(p1 == p2) {return 1;}
if(p1.x == p2.x){}
if(p1.y == p2.y){}
}
When I compile global_planner.cpp, I am getting the following error -
/home/skpro19/catkin_ws/src/my_global_planner/src/global_planner.cpp: In member function ‘bool global_planner::GlobalPlanner::generate_straight_path(const global_planner::GlobalPlanner::Point&, const global_planner::GlobalPlanner::Point&)’:
/home/skpro19/catkin_ws/src/my_global_planner/src/global_planner.cpp:150:11: error: no match for ‘operator==’ (operand types are ‘const global_planner::GlobalPlanner::Point’ and ‘const global_planner::GlobalPlanner::Point’)
if(p1 == p2) {return 1;}
The error disappears if I change the definition of generate_straight_path from generate_straight_path(const Point &p1, const Point &p2) to generate_straight_path(Point &p1, Point &p2).
Why is this happening?
Your equality operator overload is a member function, but not marked const:
bool operator==(const Point &p1 ) { return ((p1.x == x) && (p1.y == y)); }
When you turn it into a const member function, this should work as expected:
bool operator==(const Point &p1 ) const { return ((p1.x == x) && (p1.y == y)); }
It's a bit blurry through the operator, but when you look at it this way:
bool GlobalPlanner::generate_straight_path(const Point &p1, const Point &p2){
// ...
if (p1.operator==(p2)) /* ... */ ;
}
which is the more verbose way to call an member operator overload, you can see that this operator== must be const because the function argument const Point& p1 is const itself.
It is only by coincidence that you can fix it by removing a const. In fact you need to add one here:
bool operator==(const Point &p1 ) const { return ((p1.x == x) && (p1.y == y)); }
// ^^^
Otherwise you can only call operator== with a non-const left hand operand.

Passing set to templatised function

Here's my complete working code
class Point2D
{
protected:
int x, y;
public:
Point2D(int x_, int y_) : x(x_), y(y_)
{
}
int getX() const
{
return x;
}
int getY() const
{
return y;
}
bool operator< (const Point2D & pointObj) const
{
if(x == pointObj.getX() && y == pointObj.getY())
return false;
return pointObj.getX() == x ? true : x < pointObj.getX();
}
};
template<typename T, typename U>
void printSet(const set<T>& setToPrint)
{
set<T, U> pSet;
for(typename set<T>::iterator it = setToPrint.begin(); it != setToPrint.end(); it++)
{
pSet.insert(*it);
}
for(typename set<T,U>::iterator it = pSet.begin(); it != pSet.end(); it++)
{
//here print the element
}
}
int main()
{
set<Point2D> setP2;
setP2.insert(Point2D(1,3));
setP2.insert(Point2D(3,2));
int i = 1;
if(i==1)
{
printSet<Point2D, std::less<Point2D > >(setP2);
i++;
}
if(i==2)
{
printSet<Point2D, std::greater<Point2D > >(setP2);
}
}
It produces a bunch of errors from template code, but I think below is the primary one
/usr/include/c++/5/bits/stl_function.h:377:20: error: no match for ‘operator>’ (operand types are ‘const Point2D’ and ‘const Point2D’)
/usr/include/c++/5/bits/stl_function.h:377:20: note: ‘const Point2D’ is not derived from ‘const std::pair<_T1, _T2>’
What is wrong with the code?
In order to be able to create std::set<Point2D, std::greater<Point2D>>, you need to implement operator> between two objects of type Point2D.
Add a member funtion similar to operator< in the class to resolve the problem.
Suggestion for improvement
The operator< function can be simplified to user fewer compare operations.
bool operator< (const Point2D & pointObj) const
{
if ( x != pointObj.x )
{
return ( x < pointObj.x );
}
return ( y < pointObj.y );
}
The operato> function can be similarly implemented as:
bool operator> (const Point2D & pointObj) const
{
if ( x != pointObj.x )
{
return ( x > pointObj.x );
}
return ( y > pointObj.y );
}
You have implemented the < operator, not the >. C++ is pretty particular about that kind of thing. Implement operator> and you should be all set.
You can do that in terms of operator< if you like:
bool operator> (const Point2D & pointObj) const
{
if(x == pointObj.getX() && y == pointObj.getY())
return false;
return pointObj < this;
}
You can see more examples here.

Compare two SDL_point?

I noticed I can't directly compare two SDL_points:
SDL_Point a = {1, 2};
SDL_Point b = {1, 2};
if (a == b) std::cout << "a = b\n"; // Doesn't compile.
if (a.x == b.x && a.y == b.y) // I have to do this instead.
std::cout << "a = b\n";
I would like to overload the operator==, but since SDL_Point is part of SDL, I'm not sure how, because I may want to use the overloaded operator in many different classes of my game.
What's the normal way to do this?
Just have a utility or sdl_utility header that defines the operator inline:
inline bool operator==(SDL_Point const &a, SDL_Point const &b)
{
return a.x == b.x && a.y == b.y;
}
inline bool operator!=(SDL_Point const &a, SDL_Point const &b)
{
return !(a == b);
}
You will have to include this header in any source file that wants to use the operator.

Call base class overloaded operator from parent class

In the following simple structs, p3 inherits from p2.
struct p2 {
double x, y;
p2(double x, double y) : x(x),y(y){}
bool operator ==(const p2& b) const{ return x == b.x && y == b.y; }
bool operator !=(const p2& b) const{ return !(*this == b); }
};
struct p3 : p2 {
double z;
p3(double x, double y, double z) : p2(x,y),z(z){}
bool operator ==(const p3& b) const{ return x == b.x && y == b.y && z == b.z; }
bool operator !=(const p3& b) const{ return !(*this == b); }
};
In the overloaded comparison operators for p3, how can I replace the x == b.x && y == b.y part with a call to the overloaded operator from the parent class?
Just use the scoping operator :: in the derived struct
So in your operator==() in struct p3 looks like this:
bool operator==(const p3& b) const {
return p2::operator==(b) && z == b.z;
}
bool operator==(const p3& b) const
{
return p2::operator==(b) && z == b.z;
// ~~~~~~~~~~~~~~~~^
}

How to find an element in a vector?

I have defined a structure Coord as
struct Coord {
int x;
int y;
int z;
};
Overloaded operator!= for Coord
bool Coord::operator !=(Coord& crd)const {
if(this->x != crd.x)
{
if(this->y != crd.y)
{
if(this->z != crd.z)
return true;
else
return false;
}
else
return false;
return true;
}
else
return false;
}
Then initialized a vector variable as
vector<Coord> vcoord;
Now I am using following code to get index of vector having a perticular Coord object
int Index::getVIndex(Coord crd) {
vector<Coord>::iterator it;
int indx;
it = vcoord.begin();
while(it != vcoord.end() && (*it) != crd)
++it;
indx = distance(vcoord.begin(),it);
cerr << (*it).x << " " << (*it).y << " " << indx << endl;
return indx;
}
But the value of indx is always 0. Kindly help to get correct result.
You need a not-equals operator for your Coord struct in order to be able to do this:
(*it) != crd
The logic of your not-equals operator is incorrect. The best and easiest option is to provide an equality comparison and use std::find:
struct Coord {
int x;
int y;
int z;
};
bool operator == (const Coord& lhs, const Coord& rhs)
{
return lhs.x==rhs.x && lhs.y==rhs.y && lhs.z==rhs.z;
}
You can then implement != in terms of ==, but you don't need it if you use std::find, which uses == by default:
vector<Coord>::iterator it = std::find(vcoord.begin(), vcoord.end(), crd);
Your != operator returns true only if all coordinates differ; it should return true if any differ. This means your function will return zero if any coordinate of the first element matches the function argument's.
Your version is a long-winded way of writing:
return x != crd.x && y != crd.y && z != crd.z;
when it should be:
return x != crd.x || y != crd.y || z != crd.z;
It may be easier to get the logic correct by implementing it in terms of ==:
bool operator==(Coord const & lhs, Coord const & rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;
}
bool operator!=(Coord const & lhs, Coord const & rhs) {
return !(lhs == rhs);
}
Also, given a definition of ==, you can use std::find rather than rolling your own loop:
auto found == std::find(vcoord.begin(), vcoord.end(), crd);
if (found == vcoord.end()) {
// Decide what to do if not found.
// Returning zero is a bad idea, since there's no way distinguish that
// from a successful outcome.
} else {
return std::distance(vcoord.begin(), found);
}
You incorrectly implemented the logic in the inequality operator.
It should be
bool Coord::operator !=(const Coord& crd)const {
return x != crd.x || y != crd.y || z != crz.z;
}
Your implementation is logically equivalent to
return x != crd.x && y != crd.y && z != crz.z;