Jump to content
  • Advertisement
Sign in to follow this  
MeshGearFox

Pointers and STL find() function.

This topic is 3170 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Let's say I have a class XYZ, and a list of pointers to objects of class XYZ. So, list<XYZ*> myList; I want to look through this list for a specific XYZ object. So: XYZ *test; list<XYZ*>::iterator it; it = find(myList.begin(), myList.end(), test); However, that doesn't search for equivalent objects. It searches fore equivalent pointers. So, if it's even possible, how would I use find on a list of pointers to look for the actual object that's being pointed to? I tried find(*(myList).begin(), *(myList).end(), *test), which didn't give me any compiler errors, but it = couldn't handle it (I'm guessing either because it returned the wrong kind of iterator, or the pointer wizardry there is completely wrong).

Share this post


Link to post
Share on other sites
Advertisement
Use a functor template that does the dereferencing internally:

template<typename T>
class dereference
{
T* pointer;

public:

dereference(T* p) : pointer(p) {}

bool operator()(T* p)
{
return *p == *pointer;
}
};

// ...

it = find_if(test.begin(), test.end(), dereference<XYZ>(test));


If you don't want to supply the template argument yourself, you can build a helper function:

template<typename T>
class dereference_t
{
T* pointer;

public:

dereference_t(T* p) : pointer(p) {}

bool operator()(T* p)
{
return *p == *pointer;
}
};

template<typename T>
dereference_t<T> dereference(T* p)
{
return dereference_t<T>(p);
}

// ...

it = find_if(test.begin(), test.end(), dereference(test));


[Edited by - DevFred on December 4, 2009 5:16:50 AM]

Share this post


Link to post
Share on other sites
The facility DevFred outlined is available in the boost lambda library. Something like this should do the trick:


using boost::lambda::_1;
it = std::find_if(b, e, *_1 == *myXYZ);


EDIT: alternatively, just use std::list<XYZ> rather than hold the objects by pointer. You seem to be early on in the game as far as your C++ career is concerned, so I feel obliged to point out that this would usually be considered as a more normal thing to do.

Share this post


Link to post
Share on other sites
All objects of type XYZ are created at run time. Wouldn't I need it to be a list of pointers so that I could use new..?

Anyway, just for testing purposes, I posted your functor code verbatim and changed the find arguments.

So, declaration for the objects, here:

const list<SpriteSheet*> &artAssets (This is an argument, of course)
list<SpriteSheet*>::const_iterator ait;
SpriteSheet *test;

And calling find:

ait = find(artAssets.begin(), artAssets.end(), dereference<SpriteSheet>(test));

Is still giving me the following errors, which I would get a result of just passing in *test.


|n function `_InputIterator std::find(_InputIterator, _InputIterator, const _Tp&, std::input_iterator_tag) [with _InputIterator = std::_List_const_iterator<SpriteSheet*>, _Tp = dereference<SpriteSheet>]':

instantiated from `_InputIterator std::find(_InputIterator, _InputIterator, const _Tp&) [with _InputIterator = std::_List_const_iterator<SpriteSheet*>, _Tp = dereference<SpriteSheet>]'

error: no match for 'operator==' in '(&__first)->std::_List_const_iterator<_Tp>::operator* [with _Tp = SpriteSheet*]() == __val'




And I do have operator == overloaded on the SpriteSheet class, although maybe I did that wrong:


bool operator==(const SpriteSheet &rhs) const
{ if (this->sheetName == rhs.sheetName) {
return true; }
else { return false; }
}


So, uh, what am I doing wrong..?

--edit--

Getting the same issue with the boost::lambda thing.

[Edited by - MeshGearFox on December 4, 2009 12:01:17 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by MeshGearFox
All objects of type XYZ are created at run time. Wouldn't I need it to be a list of pointers so that I could use new..?

No, observe:

list<pair<int, double> > myList;

// function style constructor, template parameters necessary
myList.push_back(pair<int, double>(42, 42.0));

// helper function, no need for template parameters
myList.push_back(make_pair(42, 42.0));


Quote:
Original post by MeshGearFox
And calling find:

You need to call find_if, not find.

Quote:
Original post by MeshGearFox

bool operator==(const SpriteSheet &rhs) const
{ if (this->sheetName == rhs.sheetName) {
return true; }
else { return false; }
}


No need for the if/else, the result of the comparison is already the result you are interested in:

bool operator==(const SpriteSheet &rhs) const
{
return this->sheetName == rhs.sheetName;
}

Share this post


Link to post
Share on other sites
Ahh, thank you. Didn't see the _if there, for whatever reason.

As for your second example, I guess I just admit the new command. I was... not aware that I could do that! Interesting! I'll go restructure some things real quick here.

Share this post


Link to post
Share on other sites
Quote:
Original post by MeshGearFox
I guess I just admit the new command. I was... not aware that I could do that!

You probably have a programming background in programming languages where new is the only way to create an object (Java for example).

Share this post


Link to post
Share on other sites
Quote:
As for your second example, I guess I just admit the new command.


Brief addendum: I have absolutely no idea what this means, or what it was supposed to mean.

Also, this in general involved way too much fiddling around. See, the objects have a string name member that store's the strings name, and then a public accessor. What I WANTED to do was search through my list of objects based on the string name, which doesn't really work with find, and would work with find_if if I screwed around with the lambda functions a bit.

Or, the other option was to just look up the STL source code for the find functions, copy them into one of my own headers, and change them to do what I wanted. Which took all of five minutes.

And now I feel stupid :)

[Edited by - MeshGearFox on December 4, 2009 10:23:25 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by MeshGearFox
Quote:
As for your second example, I guess I just admit the new command.


Brief addendum: I have absolutely no idea what this means, or what it was supposed to mean.
I figured it meant he liked doing return this->sheetName == rhs.sheetName; better than the if/else. That is a strange way to say it if that is what he meant though.

edit: I didn't realize you were the one who said both things! Hilarious.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!