Page 1 of 1

operator==() how do I use it!?

Posted: Fri Jun 15, 2007 12:41 pm
by earlz
I have tried to make an operator== for a class but I keep getting errors that it either doesn't match, or it takes exactly one argument(and it says it's trying to match to a 2 argument one though!?)

here is my code

Code: Select all

//yes..I know this is probably somewhere in the STL, but anyway...
class RobotList{
	unsigned int length;
	RobotObject *first,*last;
	public:
	unsigned int GetLen(){return length;}

	RobotList(Robot *first);
	void AddToList(Robot *to_add);
	void RemoveFromList(Robot *pointer); //this only looks for the first pointer that matches..
	void RemoveFromList(unsigned int index); //this could actually be easily accomplished by using operator []
	RobotObject * const GetFromList(unsigned int index);
	//RobotObject *const FindRobot(Robot *robot);
	unsigned int const FindRobot(Robot *robot);
	//the icing on the cake that makes things simple
	Robot *operator [] (unsigned int index);
	//RobotObject *operator[](unsigned int index);
	bool operator==(const Robot &cmp1,const Robot& cmp2){return 1;}
};
and I am trying to compare somethign like
Robot *t=new....
RobotList *robots=new...
if(t==robots[0])


I always thought that it would the compiler would synthesize an == ! plus I thought this would just be comparing pointers! like not the actual object...

Posted: Fri Jun 15, 2007 12:57 pm
by Alboin
I think the declaration has to be something like:

Code: Select all

bool operator==(Robot cmp1, Robot cmp2){return 1;} 
At least, that's what a quick look in The C++ Programming Language seams to say...

Posted: Fri Jun 15, 2007 1:01 pm
by earlz
I tried that, but I thought it had to do with references or pointers...
here is the error produced when trying to use that

Code: Select all

src/LogiCode.cpp:271: error: no match for 'operator==' in 'LogiCode::crobot == *LogiCode::robots'
/mingw/include/objbase.h:79: note: candidates are: BOOL operator==(const GUID&, const GUID&)

Posted: Fri Jun 15, 2007 1:58 pm
by Colonel Kernel
You might find this useful.

From what I can see, you're neither declaring operator== as a member function nor as a global friend function, so basically you can't use it.

I think you want a declaration something like this:

Code: Select all

class Robot
{
public:
    ...
    bool operator==( const Robot& other ) const;
    ...
};
In the implementation, compare "other" to "this".
I always thought that it would the compiler would synthesize an == ! plus I thought this would just be comparing pointers! like not the actual object...
As for comparing by pointer, the only way to do that in C++ is to do it yourself:

Code: Select all

    Foo foo, bar;
    if (foo == bar) // <-- Uses operator==, if defined.
       ...
    Foo* pFoo = &foo;
    Foo* pBar = &bar;

    if (pFoo == pBar) // <-- Now you're comparing pointers. No compiler magic here.
        ...
You could always compare the addresses of "this" and "other" in your own implementation of operator==, but this is not usually what you want.

I hope this clears things up.

Posted: Fri Jun 15, 2007 2:44 pm
by earlz
what do you mean "no compiler magic" do you mean that you have to use your own operator== for pointers or what?

It's weird because I can compare two Robot pointers, but I can't compare Robot* to a function that returns a Robot* function...
like here is my straight code..

Code: Select all

	crobot=new Robot(5,2,test_brain);
	robots=new RobotList(crobot);
	robots->AddToList(new Robot(10,61,test_brain));
	robots->AddToList(new Robot(30,5,test_brain));
	if(crobot==robots[0]){cout << "pass" <<endl;} //error here
	robots->RemoveFromList(1);
and I just don't see what I'm doing wrong! I just want to basically do

Code: Select all

if(crobot(void*)==robots[0](void*))
just compare one pointer value to another pointer value...and I've tried adding that to the Robot class, and it still gives error!

Is this a bug with Mingw!!?? I mean, the error goes back into a C++ library header file!

Posted: Fri Jun 15, 2007 2:54 pm
by Tyler
hckr83 wrote:what do you mean "no compiler magic" do you mean that you have to use your own operator== for pointers or what?!
No... he means you don't need to write special code for comparing pointers. Not that i could ever invision a situation where Global, static or automatic variables could possibly point to the same location, so it really is not needed.

Posted: Fri Jun 15, 2007 3:20 pm
by Colonel Kernel
hckr83 wrote:what do you mean "no compiler magic" do you mean that you have to use your own operator== for pointers or what?
I mean, that comparison compiles down to machine code that just compares two addresses in registers. There is no automatic insertion of a call to an operator==() function or any of that crazy stuff. Comparing pointers is just comparing pointers.
It's weird because I can compare two Robot pointers, but I can't compare Robot* to a function that returns a Robot* function...
like here is my straight code..

Code: Select all

	crobot=new Robot(5,2,test_brain);
	robots=new RobotList(crobot);
	robots->AddToList(new Robot(10,61,test_brain));
	robots->AddToList(new Robot(30,5,test_brain));
	if(crobot==robots[0]){cout << "pass" <<endl;} //error here
	robots->RemoveFromList(1);
Without seeing your implementation of RobotList, it is impossible to know why you're getting an error. My guess is that your implementation of operator[] for RobotList does not return a Robot*, even though you think it does.
and I just don't see what I'm doing wrong! I just want to basically do

Code: Select all

if(crobot(void*)==robots[0](void*))
Did you mean:

Code: Select all

if ((void*) crobot == (void*) robots[0])
(It's bad practice to use C-style casts in C++, and ditto for casting to void* if it's not absolutely necessary. OT but I just thought I'd mention it.)

Posted: Fri Jun 15, 2007 3:32 pm
by earlz
Without seeing your implementation of RobotList, it is impossible to know why you're getting an error. My guess is that your implementation of operator[] for RobotList does not return a Robot*, even though you think it does.
here is the class

Code: Select all

class RobotList{
	unsigned int length;
	RobotObject *first,*last;
	public:
	unsigned int GetLen(){return length;}

	RobotList(Robot *first);
	void AddToList(Robot *to_add);
	void RemoveFromList(Robot *pointer); //this only looks for the first pointer that matches..
	void RemoveFromList(unsigned int index); //this could actually be easily accomplished by using operator []
	RobotObject * const GetFromList(unsigned int index);
	//RobotObject *const FindRobot(Robot *robot);
	unsigned int const FindRobot(Robot *robot);
	//the icing on the cake that makes things simple
	Robot *operator [] (unsigned int index); //HERE
	//RobotObject *operator[](unsigned int index);
//	bool operator==(const Robot cmp2){return 1;}
};

It does return a Robot*, I don't see how I would get confused there

and for the C casts, I just was showing what I want it to treat it like...

Posted: Fri Jun 15, 2007 4:37 pm
by Kevin McGuire
crobot=new Robot(5,2,test_brain);
robots=new RobotList(crobot);
robots->AddToList(new Robot(10,61,test_brain));
robots->AddToList(new Robot(30,5,test_brain));
if(crobot==robots[0]){cout << "pass" <<endl;} //error here
robots->RemoveFromList(1);
It is treating the robots variable as a pointer to an array of RobotList. Try:
(crobot==(*robots)[0])

Or, instead of comparing pointers -- invoke the operator == for the robot class:
(*crobot == *((*robots)[0])

Code: Select all

// ~~~~~~~~~~~~~~~~~~~~~~~
// Headers
// ~~~~~~~~~~~~~~~~~~~~~~~
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
// ~~~~~~~~~~~~~~~~~~~~~~~
// Constants And Defines
// ~~~~~~~~~~~~~~~~~~~~~~~
#define BRAIN_SIZE 5
// ~~~~~~~~~~~~~~~~~~~~~~~
// cRobot Class Declaration
// ~~~~~~~~~~~~~~~~~~~~~~~
class cRobot
{
	public:
	uint8_t brain[BRAIN_SIZE];
	cRobot();
	~cRobot();
	bool operator==(cRobot &a);
	cRobot& operator=(const cRobot &a);
};
// ~~~~~~~~~~~~~~~~~~~~~~~
// cRobotList Class Declaration
// ~~~~~~~~~~~~~~~~~~~~~~~
class cRobotList
{
	public:
	cRobot	*list[1024];
	cRobotList();
	~cRobotList();
	bool AddRobot(cRobot *a);
	cRobot* operator[](int index);
};
// ~~~~~~~~~~~~~~~~~~~~~~~
// cRobotList Class Implementation
// ~~~~~~~~~~~~~~~~~~~~~~~
cRobotList::cRobotList()
{
	memset(&list[0], 0, sizeof(list));
}
cRobotList::~cRobotList()
{
}
bool cRobotList::AddRobot(cRobot *a)
{
	uint32_t x;
	for(x = 0; x < 1024; ++x)
	{
		if(list[x] == 0)
		{
			list[x] = a;
			return true;
		}
	}
	return false;
}

cRobot* cRobotList::operator[](int index)
{
	return list[index];
}
// ~~~~~~~~~~~~~~~~~~~~~~~
// cRobot Class Implementation
// ~~~~~~~~~~~~~~~~~~~~~~~
cRobot::cRobot()
{
	memset(&brain[0], 0, BRAIN_SIZE);
}
cRobot::~cRobot()
{
}
bool cRobot::operator==(cRobot &a)
{
	uint32_t x;
	for(x = 0; (brain[x] == a.brain[x]) && (x < (BRAIN_SIZE-1)); ++x);
	return a.brain[x] == brain[x];
}
cRobot& cRobot::operator=(const cRobot &a)
{
	memcpy(&brain[0], &a.brain[0], BRAIN_SIZE);
	return *this;
}
// ~~~~~~~~~~~~~~~~~~~~~~~
// main entry
// ~~~~~~~~~~~~~~~~~~~~~~~
int main(int argc, char *argv[])
{
	cRobot *a = new cRobot(), *b = new cRobot();
	cRobotList *lst = new cRobotList();
	memset(&a->brain[0], 1, BRAIN_SIZE);
	memset(&b->brain[0], 4, BRAIN_SIZE);

	lst->AddRobot(a);
	lst->AddRobot(b);

	if(*a == *((*lst)[1]))
	{
		printf("equal.\n");
	}else{
		printf("not equal.\n");
	}
	return 1;
}

Posted: Fri Jun 15, 2007 4:43 pm
by Colonel Kernel
Doh... The problem is simple, but subtle. I just didn't see it at first.

Your variable, robots, is a RobotList*, not a RobotList or RobotList&. In order to use operator[] on it, you have to do this:

Code: Select all

(*robots)[0]
I would suggest creating the object on the stack instead of using new. In fact, I would recommend doing that in general unless your design requires you to do otherwise.

Posted: Fri Jun 15, 2007 5:52 pm
by earlz
Colonel Kernel wrote:Doh... The problem is simple, but subtle. I just didn't see it at first.

Your variable, robots, is a RobotList*, not a RobotList or RobotList&. In order to use operator[] on it, you have to do this:

Code: Select all

(*robots)[0]
I would suggest creating the object on the stack instead of using new. In fact, I would recommend doing that in general unless your design requires you to do otherwise.
Wow!! thanks!! it works like a charm!!
I guess the compiler was trying to think that robots was an array of RobotList

sadly my test didn't pass :( but that's my own problem not related to the purpose of this thread

Posted: Fri Jun 15, 2007 6:03 pm
by Colonel Kernel
hckr83 wrote:I guess the compiler was trying to think that robots was an array of RobotList
No, it thought robots was a pointer to a RobotList... because that's what you told it.

Posted: Fri Jun 15, 2007 6:20 pm
by Kevin McGuire
No, it thought robots was a pointer to a RobotList... because that's what you told it.
... it thought robots was a pointer to an array of RobotList structures.. because that is.. :wink:

Posted: Fri Jun 15, 2007 7:04 pm
by Kevin McGuire
Oh. Excuse me. All three of us are correct. It is just that we were thinking from different perspectives.

Colonel Kernel was thinking from your point of view towards the compiler, while I was thinking from the compilers point of view towards you by which you noted "I guess the compiler..."..

:P