[C++-sig] operator in return false while operator == return true

Jim Bosch talljimbo at gmail.com
Sat Sep 25 00:34:36 CEST 2010


On 09/24/2010 02:42 PM, Simon W wrote:
> Hey, sorry for the lacking information.
>
> May I declare it as this instead:
>
> C++ Class
> class GameObjectManager
> {
>      map<GameObject*, Data> a_map; // this map has "nothing" to do with
> python dict
>     GameObject* createGameObject(id)
>     {
>        Gameobject* obj = new Gameobject(id);
>        a_map[ obj ] = ...some data...
>        return obj;
>      }
>
>
>     callPython()
>    {
>        // get game object from map
>        obj = a_map.getgameobject()
>
> boost::python::get_override("callbackFunction")(boost::python::object(boost::python::ptr(obj)));
>    }
>
> }; // end of class
>
> The python class:
>
>
> class myRandomClass:
>     def __init(self, the_c++_GameobjectManager_pointer):
>       self.manager = the_c++_GameobjectManager_pointer
>       gameobject = self.manager.createGameObject(1)
> #self.manager.createGameObject() returns a pointer to the gameobject
> created in c++
>       self.mylist[gameobject] = ..some data..
>
>     def callPython(self, gameobj): # at some point, c++ will call this
> function and pass the game object we created above with id 1
>      for x in self.mylist.keys():
>        print(x == gameobj)         # True
>        print(gameobj in mylist)    # False
>
> So basically the c++ class and python class have their own dict but I
> want them to have the *same *address value in their keys .. is it possible??
>
> It seems, in c++ the key is the address of the game object and in Python
> it some other address (but they basically point to the same
> object/memory). Is there any way around this _without_ changing the type
> of the key being used, i.e. keep the key as a pointer.
>

You need to define __eq__, __ne__ and __hash__ in Python in such a way 
that they compare the C++ pointers for equality.  You can do this by 
writing free functions that take a GameObject* as their first argument, 
and wrapping them as Python methods with those special names.

That should be all you need to do.

Be aware that defining __hash__ also tells Python that you promise that 
it's return value is an immutable property of the Python object - i.e. 
the same Python object should never be changed to point to a different 
C++ object (this is hard to do accidentally anyhow in Boost.Python).

Jim



>
>
>
> On Fri, Sep 24, 2010 at 4:27 PM, Stefan Seefeld <seefeld at sympatico.ca
> <mailto:seefeld at sympatico.ca>> wrote:
>
>       Simon,
>
>     I don't quite understand what you are trying to do. Please provide a
>     little more detail. Your current mail requires far too much
>     second-guessing to be useful.
>
>
>     On 09/24/2010 10:08 AM, Simon W wrote:
>
>         Hi,
>
>         Im really scared because I fear a fundamental issue concerning
>         the script system in my game engine.
>
>
>         In C++, I have a class. In my class I map data to GameObject like:
>
>         *class
>         {
>             map<GameObject*, Data> .....
>         }*
>
>
>     OK. (Naming this class would help the discussion, though.)
>
>
>         As you see, I use the pointer as key.
>
>         When I from c++, in the same class, call a python function I
>         pass the key like this:
>
>         *class::callPythonFunctions()
>         {
>
>         boost::python::get_override("callbackFunction")(boost::python::object(boost::python::ptr(gameobject)));
>         // the variable /gameobj /is of type GameObject*
>         }
>         *
>
>
>     OK.
>
>
>         When I recieve the call in python I do some checks like this:
>
>         *def callbackFunction(self, gameobj):
>            for x in self.mydict.keys():
>              print("Checking")
>              print(gameobj == self.mydict)
>              print(gameobj in self.mydict)*
>
>
>     This looks wrong. You iterate over 'x', but don't use it in the
>     loop. May I assume that 'mydict' relates to the above
>     map<GameObject*, Data> in the unnamed class ?
>
>
>
>         The above will print something like:
>         /....
>         Checking
>         True
>         False
>         .../
>
>
>     This suggests that 'gameobj' compares equal to the 'mydict' object,
>     but that it is not itself included in the sequence returned by
>     mydict.keys().
>
>
>
>
>         I do have a overloaded == operator. But how can I fix so that
>         python checks for my pointer and not the PyObject* pointer ?
>
>
>     What type do you consider providing an operator== for ?
>
>         Stefan
>
>
>     --
>
>           ...ich hab' noch einen Koffer in Berlin...
>
>     _______________________________________________
>     Cplusplus-sig mailing list
>     Cplusplus-sig at python.org <mailto:Cplusplus-sig at python.org>
>     http://mail.python.org/mailman/listinfo/cplusplus-sig
>
>
>
>
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig



More information about the Cplusplus-sig mailing list