operator== in C++ struct [duplicate] - c++

This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 1 year ago.
I'm trying to define an == operator in a structure:
typedef struct _tBScan {
QString strQuadpackNumbers;
uint uintBegin, uintEnd;
bool operator==(const struct _tBScan& a, const struct _tBScan& b) {
return (a.strQuadpackNumbers.compare(b.strQuadpackNumbers) == 0 &&
a.uintBegin == b.uintBegin && a.uintEnd == b.uintEnd);
}
} tBScan;
This won't compile, I get:
C2804: binary 'operator ==' has too many parameters
C2333: '_tBScan::operator ==' error in function: declaration: skipping function body
I'm using Qt 5.9.2 and MSVC 2015, I need to define this so I can use the QList compare function.

When overloading an binary operator as a member function, the first parameter is this pointer. In the signature you have defined the operator==, it will take 3 arguments. However, it can only take two.
In you case I would recommend making it a non-member function.
typedef struct _tBScan {
QString strQuadpackNumbers;
uint uintBegin, uintEnd;
} tBScan;
bool operator==(const struct _tBScan& a, const struct _tBScan& b) {
return (a.strQuadpackNumbers.compare(b.strQuadpackNumbers) == 0 &&
a.uintBegin == b.uintBegin && a.uintEnd == b.uintEnd);
}
When you overload the, let's say, operator# the expression _tBScan # _smt is resolved into.
_tBScan.operator#(_smt);
When it's not a member function the expression is resolved into
operator#(_tBScan, _smt);
So the compiler searches the overload of either of them.

Related

How to use Insert in Set for Custom Data Type ? C++ [duplicate]

This question already has an answer here:
std::set.insert won't compile with custom class [duplicate]
(1 answer)
Closed 9 months ago.
class Game()
{
void add(set<Velocity> & v);
}
class Velocity()
{
private:
// Member Variables
public:
// Constructors and methods
}
void Game::add(set<Velocity> &velocities)
{
Velocity v;
v.setVelocity();
v.setSource();
velocities.insert(v);
}
As you can see I have a custom class called Game and it has a public method called Add which adds a velocity object to the set. When the insert(v) code executes it throws me an error: invalid operands to binary expression ('const Velocity' and 'const Velocity')
{return __x < __y;}
I am not sure how to fix this, I would appreciate any help or suggestions. Thanks a bunch.
In std::set...
sorting is done using the key comparison function...
You need to look toward something like this:
bool operator<(const Velocity&, const Velocity&);
class Velocity {
friend bool operator<(const Velocity&, const Velocity&);
private:
unsigned velocity_value;
// ...
};
bool operator<(const Velocity& a, const Velocity& b)
{
return a.velocity_value < b.velocity_value;
}
Note, however that in this example, there won't be possible to have two different elements of type Velocity with the same velocity_value, since...
std::set is an associative container that contains a sorted set of
unique objects of type Key
If you need to add all the supplied Velocity objects in an instance of the Game, you may need to reconsider the choice of the container, or some other mean of comparison.

Invalid arguments when calling getter member

The error happen when I try to use one of my get function on parameter inside member functions. The error is:
Invalid arguments '. Candidates are : int getTotalArea() .
here is an example from my code :
class Apartment{
public : // ...
enum SquareType {EMPTY, WALL, NUM_SQUARE_TYPES};
bool operator<(const Apartment& apartment); // done - need help
int getTotalArea(); // done
private:
int price;
int length;
int width;
SquareType** squares;
};
int Apartment::getTotalArea()
{
int count=0;
for(int i=0;i<width;i++)
{
for(int j=0;j<length;j++)
{
if(squares[i][j]==EMPTY)
{
count++;
}
}
}
return count;
}
bool Apartment::operator<(const Apartment& apartment)
{
int thisArea=this->getTotalArea();
int paramArea=apartment.getTotalArea(); // the error line is here !!!
//the error is Invalid arguments '. Candidates are : int getTotalArea() .
double thisRatio=((double)price)/thisArea;
double paramRatio=((double)apartment.price)/paramArea;
if(thisRatio==paramRatio)
{
return price < apartment.price;
}
return thisRatio<paramRatio;
}
Have I done something wrong ?
It's the first time I'm using c++ ... by the way - any comments for the rest of the code are fine as well.
From the answer of PcAF seems you've heavily changed your initial post without modifying your question. Very bad!
However, the problem you're facing now with getTotalArea is that it isn't declared const.
See https://stackoverflow.com/a/751690/781933 for explanation.
Seems like you misunderstood operator overloading (as members)
When overloading some operator as member, then first operand of that operator is object on which member operator overload is called and second operand is parameter to that function (in case of binary operators).
operator + can be used as binary(2 operands) or unary operator(1 operand).
Here it seems like you want to overload binary version as member:
Apartment operator+(const Apartment& apartment1,const Apartment& apartment2);
but since first operand is object on which that member "function" is called it must take only 1 parameter (which is second operand).
Apartment operator+(const Apartment& apartment2);
Here is the second mistake:
Apartment& operator=(SquareType** squares, int length, int width, int price);
operator = is binary operator (2 operands), therefore if you want to overload it as member function it has to take exactly one parameter (which is second operand of =), not 4 parameters.

operator== not working in template function

I am writing a template function which takes in a vector and a struct, and inserts that struct into the vector. If there is a duplicate struct in the vector however,the function will not insert the struct because the values must all be unique. In order to do this, I am using the find function of the STL library, and analyzing the return value using the operator==. However, I am getting this error every time I try and compile:
error: no match for 'operator==' (operand types are 'OneToOneMap' and'OneToOneMap')|
My template function can be seen below:
template<typename Type> void AddToList(vector<Type> add_to, Type to_insert){
bool contains_element = *find( add_to.begin(), add_to.end(), to_insert) == *add_to.end() ? false:true;
if(contains_element){
cout << "Element is already in list" << endl;
}else{
add_to.push_back(to_insert);
}
}
The question isn't entirely clear however I suspect you haven't overloaded the operator== in the class/struct OneToOneMap which you are trying to compare in your code. Assuming this is a user-defined type, overload this operator (and operator!=) as follows:
class OneToOneMap {
public:
//...
bool operator==(const OneToOneMap& _other) const {
// do comparison based on fields
}
bool operator!=(const OneToOneMap& _other) const {
return !(*this == _other);
}
};
Edit
Ineed, you need to provide an overload for the type that you want to use std::find<T>() on! The reason is that of course the function needs a way to compare the container elements to find out if they're equal or not. Provide an overload for the bool T::operator==(const T& other) as ArchbishopOfBanterbury has noticed.
(To be more exact, comparison using the bool operator==(...) is used when the user has not provided another predicate to compare the elements, see http://en.cppreference.com/w/cpp/algorithm/find)
Original answer:
Remove the unnecessary dereference operators * when comparing iterators:
bool contains_element = find( add_to.begin(), add_to.end(), to_insert) == add_to.end() ? false:true;
You don't need the false : true either, since the comparison returns a bool:
bool contains_element = find( add_to.begin(), add_to.end(), to_insert) == add_to.end();
The logic is that the std::find<T>() function returns an iterator, and you compare that iterator to the vector<T>::end() iterator, i.e. the "null" iterator, to check if find<T>() has been able to find anything or not. You don't need to compare the T values themselves.

Evaluating C++ pointer to function expression [duplicate]

This question already has answers here:
How to call through a member function pointer?
(2 answers)
Closed 8 years ago.
I have a C++ class which contains the following definition:
class SomeClass:
public BaseClass
{
public:
SomeClass();
bool SomeClass::MyFunc( Json::Value& jsonRoot)
typedef bool(SomeClass::*PFUNC)(Json::Value&);
std::map<std::string, PFUNC> m_map;
}
later on in the c++ code i add values to the map variable using the following line:
SomeClass::SomeClass()
{
m_map["func"] = &SomeClass::MyFunc;
}
and for execution within one of SomeClass's methods:
std::map<std::string, PFUNC>::iterator itFunction = m_map.find("func");
if (itFunction != m_map.end())
{
PFUNC pfParse = m_map["func"];
Json::Value x;
this->*pfParse(x);
}
I end up getting the following compilation error:
error C2064: term does not evaluate to a function taking 1 arguments
I even tried using the iterator explicitly - this->*iterator->second(...) but ended up with the same error.
what am i doing wrong?
thanks
() has higher precedence than ->* so pfParse(x) is evaluated first. You need to use parenthesis to sequence the evaluation:
(this->*pfParse)(x);

When to pass by reference for overloading operators in c++?

I have implemented a custom pointer class, lets call it japan. Here is a declaration and definition, as well as a main function I am trying to work with.
class japan
{
public:
japan(T *ptr) : ptr(ptr)
{}
T *get()
{
return this->ptr;
}
bool operator==(const T *&other)
{
return ( this->get() == other );
}
friend bool operator==(const T *&l, japan<T> r)
{
return ( r == l );
}
private:
T *ptr;
};
int main(void)
{
int j;
int *k = & j;
japan<int> nihon(k);
if(k == nihon)
if(nihon == k)
std::cout << "yay\n";
if(nihon == NULL)
return 1;
else
return 0;
if(NULL == nihon)
return 5;
}
My == operator seem to working fine on actual T *s when they are passed in, however if I evoke it with NULL my compiler produces the errors:
stuff.cpp:40:15: error: no match for 'operator==' in '0l == nihon'
stuff.cpp:40:15: note: candidate is:
stuff.cpp:21:16: note: bool operator==(const int*&, japan<int>)
stuff.cpp:21:16: note: no known conversion for argument 1 from 'long int' to 'const int*&'
From what I understand... there should be some form of conversion from T * to long int, or NULL's assignment operator would not function. I then reworked my operator a little.
Both of these functions work
friend bool operator==(T *l, japan<T> r);
friend bool operator==(const T *l, japan<T> r);
However This one fails.
friend bool operator==(const T *&l, japan<T> r);
This makes scene to me, changing NULL would change a value that is never used, but it is a const reference... so why does this fail. Is it common in c++ to not use references on boolean operators? Most of the examples I see always use a reference, but this seems like this would only work for lvalues... So is it better practice to pass by value while overloading?
ALSO:
Why would I get the warning :
warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default]
ptr.h:106:9: note: candidate 1: bool japan<T>::operator==(const T* const&) const [with T = Geometry]
stuff.cpp:239:15: note: candidate 2: operator==(int, long int) <built-in>
Is my japan class somehow exposing its self as a T when == is used, I ask this because I found this class in something I was working on with no == operator defined (despite it being used in many places), and I added one... only to find no end of problems.
In C++, 0 is an abused integer. It is used to reflect, well, 0 as a value of type int and it is also used to represent a null pointer.
Your types are fundamentally different. There's no const correctness issue, it's just that NULL, is a macro for 0 and that's something that doesn't cooperate well with generic programming. You could try
static_cast<T*>(NULL);
when comparing with null pointer, or better yet use nullptr, which is what the new standard wants you to be using when you mean "a null pointer"