Check if structure is not in vector - c++

I have a vector of structs. I need to check if the struct is or is not in the vector. The entire struct, not any specific member. It throws me this error upon compile time:
binary '==' : no operator found which takes a left-hand operand of type 'NavigationNode'
(or there is no acceptable conversion)
My struct:
struct NavigationNode{
int x, y; //their x and y position on the grid
float f, g, h;
int parentGCost;
int value;
};
NavigationNode currentNode;
The vector
vector<NavigationNode> openList;
My find:
if (find(closedList.begin(), closedList.end(), currentNode) == closedList.end() )
{
}

You need to overload operator==.
As global function:
bool operator==( const NavigationNode& lhs, const NavigationNode& rhs )
{
// compare lhs and rhs
}
Or as member function:
bool operator==( const NavigationNode& other ) const
{
// compare this & other
}

You will have to write an equality operator for your custom type. Assuming all variables have to be the same for two NavigationNode objects to be the same, it should look something like this:
bool floatEqual(float a, float b)
{
// adapt this comparison to fit your use-case - see the notes below
static const int EPSILON = 0.00001; // arbitrarily chosen - needs to be adapted to the occuring values!
return std::abs(a – b) <= EPSILON;
}
bool operator==(NavigationNode const & a, NavigationNode const & b)
{
return a.x == b.x &&
a.y == b.y &&
floatEqual(a.f, b.f) &&
floatEqual(a.g, b.g) &&
floatEqual(a.h, b.h) &&
a.parentGCost == b.parentGCost &&
a.value == b.value;
}
Even if you could also do it as a member function of NavigationNode, the recommended way is to implement the operator== as a free function (that way, both parameters can take advantage of any possible implicit conversions).
Note on float comparison: Due to how floating point numbers are represented, it is not a trivial task to compare them. Just checking for equality might not give the desired results. See e.g. this question for details:
What is the most effective way for float and double comparison?

You need to overload the comparison operator.
If your intention of "==" is "are each of the values contained in my struct equal to the corresponding members in this other struct" then you can write that.
bool operator==(const NavigationNode& lhs, const NavigationNode& rhs)
{
return /* compare each member in here */
}

Related

Multiple operator override behaviors by manipulating type

So let's say I'm overwriting the inequality checks of a structure describing a point. I have it set to compare the magnitude by default.
I want to have an option to check each value instead, and I was thinking of ways to do it inline. I could make a function that recasts it as a dummy structure so it has a different type when comparing.
struct vec3 {
double x,y,z;
struct _all {double x,y,z};
friend _all All (vec3 &A) { return *(_all*) &vec3;}
struct _any {double x,y,z};
friend _any Any (vec3 &A) { return *(_any*) &vec3;}
friend bool operator < (vec3 &A, double B) { /* does the magnitude check */ }
friend bool operator < (_all &A, double B) { return A.x<B && A.y < B && A.z<B; }
friend bool operator < (_any &A, double B) { return A.x<B || A.y < B || A.z<B; }
};
This is all so I can write
if (All(PointA) < Limit) {}
I have a feeling this breaks a bunch of coding practices, but I'm having a hard time finding any similar problem. Maybe it's safer to use a constructor instead of type changes? Or would it be clearer if I wrote a function IsAnyLessThan(double A) for my structure instead?

Invalid Operands to binary expression(const point and const point

map<pair<int,int>,int>pairOfNumbers;
pairOfNumbers.insert(pair<pair<int,int>,int>({1,2},2));
this is working, but
map<pair<point,point>,int>PointsOnLine;
PointsOnLine.insert(pair<pair<point,point>,int>(make_pair(points[i],points[j]),count));
this doesn't.
point is just a structure of two ints x and y;
I keep getting the error 'Invalid Operands to binary expression(const point and const point' this is the structure of point.
struct point
{
int x;
int y;
public:
bool operator==(const point& p)
{
if(x==p.x && y==p.y)
return true;
else
return false;
}
bool operator!=(const point& p)
{
if(x==p.x &&y==p.y)
return false;
else
return true;
}
};
how do I insert two points and distance between them in the map?
in Xcode I get this error
Your point type does not support weak-ordering. It has no method of determining is-less-than. You may think you don't need that because your point is actually tucked into a std::pair<point,point> but you do.
std::pair<T1,T2> supports weak ordering only if T1 and T2 do. In your case, they're the same type, so for a std::pair<point,point> to be used as key in a std::map<std::pair<point,pint>,T>, point must support weak ordering.
To support weak ordering, you must either provide an operator< that compares two of your objects in question, or a comparator functor type that does the same thing. The easiest way for you to do this would be:
#include <tuple>
struct point
{
int x;
int y;
bool operator <(const point& p) const
{
return std::tie(x, y) < std::tie(p.x, p.y);
}
bool operator ==(const point& p) const
{
return !(*this < p || p < *this);
}
bool operator !=(const point& p) const
{
return *this < p || p < *this;
}
};
I took liberty to redefine operator == and operator != to utilize the weak order properties of the proper operator <. It wasn't necessary, but ultimately it's just easier if operators root to as basic code as possible. With the above change you should be able to use both point and std::pair<point,point> as key types in std::map and std::set. In truth, a strict weak ordering can define all of the basic comparators (<=, >, >=, !=, ==) as derivations from operator < in one form or another (or relative to something that does). I challenge you to consider them, try implementing them, and above all, writing some test harnesses that verify your implementation.

C2678 when compiling. Visual Studio refers to xutility [duplicate]

This question already has answers here:
How to use std::find() with vector of custom class?
(2 answers)
Closed last year.
If I have a class
class Point
{
public:
Point() {}
Point(int _col, int _row) : row(_row), col(_col) {}
int row, col;
};
how can I use std::find() to check whether the point is already in vector? DO I have to overload operator== ?
I am trying to do this
#include <algorithm>
if(std::find(v.begin(), v.end(), x) != v.end()) {
/* v contains x */
} else {
/* v does not contain x */
}
Almost every answer I find on Stack Overflow suggest using find to check whether the object is in std::vector but none of them explains whether it compares the pointer of objects or the actual values of the object.
The C++ standard (draft N3242) says (in section 25.2.5 [alg.find]) that std::find:
Returns: The first iterator i in the range [first,last) for which the following corresponding conditions hold: *i == value[...]. Returns last if no such iterator is found.
Your question of whether it will search based on the value or the address of the object depends on how operator== is implemented. The simple answer is: std::find will return an iterator to the object for which operator== returned true.
Usually, this will just be a value-based comparison (because operator== is usually implemented to compare the values of two objects), and so you should generally expect std::find to search the range for the value you've provided (not the address of the object you provided).
It's possible for operator== to be implemented such that it compares based on address, like so:
bool operator==(const Point& left, const Point& right) {
return &left == &right;
}
Using this operator== will compare addresses, and so std::find will search for an object that has the same address as the one you've provided. It's generally a bad idea to implement operator== like this, though. Most people would implement operator== like so:
bool operator==(const Point& left, const Point& right) {
return left.row == right.row && left.col == right.col;
}
which, when used with std::find, will compare Points based on their values.
Unless your types are PODs fundamental types, you will need to provide an equality function, member or not.
There are two fundamental versions of std::find, one that assumes an equality operator and the other uses an equality function you supply.
I recommend that you add operator== and operator< to any class that will be compared for equality or ordered.
Here's an updated version of your class:
class Point
{
int x; // These are private by default.
int y;
public:
Point(int new_x, int new_y) : x(new_x), y(new_y)
{ ; }
bool operator==(const Point& p) const
{
return (x == p.x) && (y == p.y);
}
};
The member method operator== allows comparison without exposing the values to friends or the public.
If you want to use a free standing comparison function, you will need to either make the values public or make the function a friend:
class Point
{
int x; // These are private by default.
int y;
public:
Point(int new_x, int new_y) : x(new_x), y(new_y)
{ ; }
friend bool operator==(const Point& a, const Point& b);
};
bool operator==(const Point& a, const Point& b)
{
return (a.x == b.x) && (a.y == b.y);
}
If you want to use the free standing function with std::find, the example would be:
std::vector<Point> point_container;
//...
Point p;
std::vector<Point>::const_iterator iter;
iter = std::find(point_container.begin(), point_container.end(),
p,
Equal_Points);
Where Equal_Points is a free standing function that can compare the members of two Points.

std::find how does it work? operator== [duplicate]

This question already has answers here:
How to use std::find() with vector of custom class?
(2 answers)
Closed last year.
If I have a class
class Point
{
public:
Point() {}
Point(int _col, int _row) : row(_row), col(_col) {}
int row, col;
};
how can I use std::find() to check whether the point is already in vector? DO I have to overload operator== ?
I am trying to do this
#include <algorithm>
if(std::find(v.begin(), v.end(), x) != v.end()) {
/* v contains x */
} else {
/* v does not contain x */
}
Almost every answer I find on Stack Overflow suggest using find to check whether the object is in std::vector but none of them explains whether it compares the pointer of objects or the actual values of the object.
The C++ standard (draft N3242) says (in section 25.2.5 [alg.find]) that std::find:
Returns: The first iterator i in the range [first,last) for which the following corresponding conditions hold: *i == value[...]. Returns last if no such iterator is found.
Your question of whether it will search based on the value or the address of the object depends on how operator== is implemented. The simple answer is: std::find will return an iterator to the object for which operator== returned true.
Usually, this will just be a value-based comparison (because operator== is usually implemented to compare the values of two objects), and so you should generally expect std::find to search the range for the value you've provided (not the address of the object you provided).
It's possible for operator== to be implemented such that it compares based on address, like so:
bool operator==(const Point& left, const Point& right) {
return &left == &right;
}
Using this operator== will compare addresses, and so std::find will search for an object that has the same address as the one you've provided. It's generally a bad idea to implement operator== like this, though. Most people would implement operator== like so:
bool operator==(const Point& left, const Point& right) {
return left.row == right.row && left.col == right.col;
}
which, when used with std::find, will compare Points based on their values.
Unless your types are PODs fundamental types, you will need to provide an equality function, member or not.
There are two fundamental versions of std::find, one that assumes an equality operator and the other uses an equality function you supply.
I recommend that you add operator== and operator< to any class that will be compared for equality or ordered.
Here's an updated version of your class:
class Point
{
int x; // These are private by default.
int y;
public:
Point(int new_x, int new_y) : x(new_x), y(new_y)
{ ; }
bool operator==(const Point& p) const
{
return (x == p.x) && (y == p.y);
}
};
The member method operator== allows comparison without exposing the values to friends or the public.
If you want to use a free standing comparison function, you will need to either make the values public or make the function a friend:
class Point
{
int x; // These are private by default.
int y;
public:
Point(int new_x, int new_y) : x(new_x), y(new_y)
{ ; }
friend bool operator==(const Point& a, const Point& b);
};
bool operator==(const Point& a, const Point& b)
{
return (a.x == b.x) && (a.y == b.y);
}
If you want to use the free standing function with std::find, the example would be:
std::vector<Point> point_container;
//...
Point p;
std::vector<Point>::const_iterator iter;
iter = std::find(point_container.begin(), point_container.end(),
p,
Equal_Points);
Where Equal_Points is a free standing function that can compare the members of two Points.

memcmp vs multiple equality comparisons

Precondition: Consider such a class or struct T, that for two objects a and b of type T
memcmp(&a, &b, sizeof(T)) == 0
yields the same result as
a.member1 == b.member1 && a.member2 == b.member2 && ...
(memberN is a non-static member variable of T).
Question: When should memcmp be used to compare a and b for equality, and when should the chained ==s be used?
Here's a simple example:
struct vector
{
int x, y;
};
To overload operator == for vector, there are two possibilities (if they're guaranteed to give the same result):
bool operator==(vector lhs, vector rhs)
{ return lhs.x == rhs.x && lhs.y == rhs.y; }
or
bool operator==(vector lhs, vector rhs)
{ return memcmp(&lhs, &rhs, sizeof(vector)) == 0; }
Now if a new member were to be added to vector, for example a z component:
If ==s were used to implement operator==, it would have to be modified.
If memcmp was used instead, operator== wouldn't have to be modified at all.
But I think using chained ==s conveys a clearer meaning. Although for a large T with many members memcmp is more tempting. Additionally, is there a performance improvement from using memcmp over ==s? Anything else to consider?
Regarding the precondition of memcmp yielding the same result as member-wise comparisons with ==, while this precondition is often fulfilled in practice, it's somewhat brittle.
Changing compilers or compiler options can in theory break that precondition. Of more concern, code maintenance (and 80% of all programming work is maintenance, IIRC) can break it by adding or removing members, making the class polymorphic, adding custom == overloads, etc. And as mentioned in one of the comments, the precondition can hold for static variables while it doesn't hold for automatic variables, and then maintenance work that creates non-static objects can do Bad Things™.
And regarding the question of whether to use memcmp or member-wise == to implement an == operator for the class, first, this is a false dichotomy, for those are not the only options.
For example, it can be less work and more maintainable to use automatic generation of relational operator overloads, in terms of a compare function. The std::string::compare function is an example of such a function.
Secondly, the answer to what implementation to choose depends strongly on what you consider important, e.g.:
should one seek to maximize runtime efficiency, or
should one seek to create clearest code, or
should one seek the most terse, fastest to write code, or
should one seek to make the class most safe to use, or
something else, perhaps?
Generating relational operators.
You may have heard of CRTP, the Curiously Recurring Template Pattern. As I recall it was invented to deal with the requirement of generating relational operator overloads. I may possibly be conflating that with something else, though, but anyway:
template< class Derived >
struct Relops_from_compare
{
friend
auto operator!=( const Derived& a, const Derived& b )
-> bool
{ return compare( a, b ) != 0; }
friend
auto operator<( const Derived& a, const Derived& b )
-> bool
{ return compare( a, b ) < 0; }
friend
auto operator<=( const Derived& a, const Derived& b )
-> bool
{ return compare( a, b ) <= 0; }
friend
auto operator==( const Derived& a, const Derived& b )
-> bool
{ return compare( a, b ) == 0; }
friend
auto operator>=( const Derived& a, const Derived& b )
-> bool
{ return compare( a, b ) >= 0; }
friend
auto operator>( const Derived& a, const Derived& b )
-> bool
{ return compare( a, b ) > 0; }
};
Given the above support, we can investigate the options available for your question.
Implementation A: comparison by subtraction.
This is a class providing a full set of relational operators without using either memcmp or ==:
struct Vector
: Relops_from_compare< Vector >
{
int x, y, z;
// This implementation assumes no overflow occurs.
friend
auto compare( const Vector& a, const Vector& b )
-> int
{
if( const auto r = a.x - b.x ) { return r; }
if( const auto r = a.y - b.y ) { return r; }
return a.z - b.z;
}
Vector( const int _x, const int _y, const int _z )
: x( _x ), y( _y ), z( _z )
{}
};
Implementation B: comparison via memcmp.
This is the same class implemented using memcmp; I think you'll agree that this code scales better and is simpler:
struct Vector
: Relops_from_compare< Vector >
{
int x, y, z;
// This implementation requires that there is no padding.
// Also, it doesn't deal with negative numbers for < or >.
friend
auto compare( const Vector& a, const Vector& b )
-> int
{
static_assert( sizeof( Vector ) == 3*sizeof( x ), "!" );
return memcmp( &a, &b, sizeof( Vector ) );
}
Vector( const int _x, const int _y, const int _z )
: x( _x ), y( _y ), z( _z )
{}
};
Implementation C: comparison member by member.
This is an implementation using member-wise comparisons. It doesn't impose any special requirements or assumptions. But it's more source code.
struct Vector
: Relops_from_compare< Vector >
{
int x, y, z;
friend
auto compare( const Vector& a, const Vector& b )
-> int
{
if( a.x < b.x ) { return -1; }
if( a.x > b.x ) { return +1; }
if( a.y < b.y ) { return -1; }
if( a.y > b.y ) { return +1; }
if( a.z < b.z ) { return -1; }
if( a.z > b.z ) { return +1; }
return 0;
}
Vector( const int _x, const int _y, const int _z )
: x( _x ), y( _y ), z( _z )
{}
};
Implementation D: compare in terms of relational operators.
This is an implementation sort of reversing the natural order of things, by implementing compare in terms of < and ==, which are provided directly and implemented in terms of std::tuple comparisons (using std::tie).
struct Vector
{
int x, y, z;
friend
auto operator<( const Vector& a, const Vector& b )
-> bool
{
using std::tie;
return tie( a.x, a.y, a.z ) < tie( b.x, b.y, b.z );
}
friend
auto operator==( const Vector& a, const Vector& b )
-> bool
{
using std::tie;
return tie( a.x, a.y, a.z ) == tie( b.x, b.y, b.z );
}
friend
auto compare( const Vector& a, const Vector& b )
-> int
{
return (a < b? -1 : a == b? 0 : +1);
}
Vector( const int _x, const int _y, const int _z )
: x( _x ), y( _y ), z( _z )
{}
};
As given, client code using e.g. > needs a using namespace std::rel_ops;.
Alternatives include adding all other operators to the above (much more code), or using a CRTP operator generation scheme that implements the other operators in terms of < and = (possibly inefficiently).
Implementation E: comparision by manual use of < and ==.
This implementation is the result not applying any abstraction, just banging away at the keyboard and writing directly what the machine should do:
struct Vector
{
int x, y, z;
friend
auto operator<( const Vector& a, const Vector& b )
-> bool
{
return (
a.x < b.x ||
a.x == b.x && (
a.y < b.y ||
a.y == b.y && (
a.z < b.z
)
)
);
}
friend
auto operator==( const Vector& a, const Vector& b )
-> bool
{
return
a.x == b.x &&
a.y == b.y &&
a.z == b.z;
}
friend
auto compare( const Vector& a, const Vector& b )
-> int
{
return (a < b? -1 : a == b? 0 : +1);
}
Vector( const int _x, const int _y, const int _z )
: x( _x ), y( _y ), z( _z )
{}
};
What to choose.
Considering the list of possible aspects to value most, like safety, clarity, efficiency, shortness, evaluate each approach above.
Then choose the one that to you is clearly best, or one of the approaches that seem about equally best.
Guidance: For safety you would not want to choose approach A, subtraction, since it relies on an assumption about the values. Note that also option B, memcmp, is unsafe as an implementation for the general case, but can do well for just == and !=. For efficiency you should better MEASURE, with relevant compiler options and environment, and remember Donald Knuth's adage: “premature optimization is the root of all evil” (i.e. spending time on that may be counter-productive).
If, as you say, you've chosen types such that the two solutions yield the same results (presumably, then, you have no indirect data and the alignment/padding is all the same), then clearly you can use whichever solution you like.
Things to consider:
Performance: I doubt you'll see much if any difference, but measure it to be sure, if you care;
Safety: Well you say the two solutions are the same for your T, but are they? Are they really? On all systems? Is your memcmp approach portable? Probably not;
Clarity: If your preconditions ever change and you did not adequately comment-describe your memcmp usage, then your program is liable to break — you've therefore made it fragile;
Consistency: Presumably you use == elsewhere; certainly you'll have to do it for every T that doesn't meet your preconditions; unless this is a deliberate optimising specialisation for T, you may consider sticking to a single approach throughout your program;
Ease of use: Of course, it's pretty easy to miss out a member from chained ==, especially if your list of members ever grows.
If two solutions are both correct, prefer the more readable one. I'd say that for a C++ programmer, == is more readable than memcmp. I would go so far as to use std::tie instead of chaining:
bool operator==(const vector &lhs, const vector &rhs)
{ return std::tie(lhs.x, lhs.y) == std::tie(rhs.x, rhs.y); }
If any only if the structure is POD and if it is safely memcmp comparable (not even all numeric types are...) the result is the same and the question is about readability and performance.
Readability? This is a rather opinion based question I think but I'd prefer operator==.
Performance? operator== is a short-circuit operator. You have more control over your program here because you can reorder the comparison sequence.
Although a == b && c == d and c == d && a == b are equivalent in terms of algorithmic logic (result is the same) they aren't equivalent in terms of produced assembly, "background logic" and possibly performance.
You can influence your program if you can forsee some points.
In example:
If both statements are roughly equally likely to yield false, you'll want to have the cheaper statement first to skip the more complex comparison if possible.
If both statements are roughly equally complex and you know in advance that c == d is more likely to be false than a == b, you should compare c and d first.
It is possible to adjust the comparison sequence in a problem-dependant fashion using operator== whereas memcmp does not give you this kind of freedom.
PS: You would want to measure it but for a small struct with 3 members, MS VS 2013 produces slightly more complex assembly for the memcmp case. I'd expect the operator== solution to have a higher performace (if the impact would be measurable) in this case.
-/edith-
Note: Even POD struct members can have overloaded operator==.
Consider:
#include <iostream>
#include <iomanip>
struct A { int * p; };
bool operator== (A const &a, A const &b) { return *(a.p) == *(b.p); }
struct B { A m; };
bool operator== (B const &a, B const &b) { return a.m == b.m; }
int main()
{
int a(1), b(1);
B x, y;
x.m.p = &a;
y.m.p = &b;
std::cout << std::boolalpha;
std::cout << (memcmp(&x, &y, sizeof(B)) == 0) << "\n";
std::cout << (x == y) << "\n";
return 0;
}
Prints
false
true
Even if -in turn- all the members are fundamental types I would prefer operator== and leave it to the compiler to consider optimizing the comparison into whatever assembly it considers to be preferable.
== is better, because memcmp compares pure memory data(comparing that way can be wrong in many situations, such as std::string, array-imitiating classes or types that can be equal even if they aren't perfectly identical). Since inside your classes there may be such types, you should always use their own operators instead of comparing raw memory data.
== is also better because it's more readable than some weird-looking function.
You imposed a very strong condition that there is no padding (I assume neither between the members of the class, nor inside these members). I presume that you also intended to exclude any "hidden" housekeeping data from the class. In addition the question itself implies that we always compare objects of exactly the same type. Under such strong conditions there's probably no way to come up with a counterexample that would make the memcmp-based comparison to differ from == comparison.
Whether it makes it worth it to use memcmp for performance reasons... well, if you really have a good reason to aggressively optimize some critical piece of code and profiling shows that there's improvement after switching from == to memcmp, then definitely go ahead. But I wouldn't use it a a routine technique for writing comparison operators, even if your class satisfies the requirements.