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
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.
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.
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.
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;
// ~~~~~~~~~~~~~~~~^
}
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;