I'm trying to find an object in an std::list of objects, and remove it and I was going to look for the NAME of the object as a basis of comparison, something like this:
PHP Code:
class myObj
{
string name;
int A;
int B;
//......
int Z;
}
//then later in the code....
list<myObj> myList;
list<myObj>::iterator itr;
itr = find(myList.begin(),myList.end(), /*look for myObj name */ );
if (itr != myList.end())
{
itr = myList.erase(itr);
}
Question is, how do I lok for just the NAME using the find command?
1) I think you want to use find_if() instead of find() , since
you are not checking the ENTIRE object for equality,
just part of the object.
2) the tricky part in creating the predicate, is you want
to pass it the name that you are looking for. There
is a "bnd2nd()" function that does this. I think sample
code will make it clearer :
Code:
#include <list>
#include <string>
#include <functional> // for binary_function and bnd2nd()
#include <algorithm> // for find_if
using namespace std;
class myObj
{
public:
string name;
int A;
int B;
int Z;
};
struct CompareName : public std::binary_function<myObj,std::string,bool >
{
bool operator () (const myObj& obj, const std::string& name) const
{
return obj.name == name;
}
};
int main()
{
list<myObj> myList;
list<myObj>::iterator itr;
// add to list
// remove FIRST occurence of object with name of "Jones"
itr = find_if(myList.begin(),myList.end(), bind2nd(CompareName(),"Jones"));
if (itr != myList.end())
{
itr = myList.erase(itr);
}
return 0;
}
Then again if your list gets very large you're better of using a map or set instead.
the cool thing with sets is you can overload the comparison function with your own struct.
struct MyCompare
{
bool operator()(YourObject *p1,YourObject * p2)const
{
//compare anyway your want and return true if bigger,or false if //smaller
}
};
typedef std::set<YourObject*,MyCompare> MySet;
Last edited by fransn; October 9th, 2003 at 02:03 PM.
Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
-- Sutter and Alexandrescu, C++ Coding Standards
Programs must be written for people to read, and only incidentally for machines to execute.
-- Harold Abelson and Gerald Jay Sussman
The cheapest, fastest and most reliable components of a computer system are those that aren't there. -- Gordon Bell
Sorry for bumping the thread but I didn't want to create a new one as I found this one.
I kinda need to do the same thing but the problem with me is that my object name is a private member of myObj class.
I have a get accessor though something like:
Code:
string getObjectName(){return name};
but when I implement it in the code above the following way:
Code:
return obj.getObjectName()== name;
I get the following error:
Code:
passing `
const myObj' as `this' argument of `std::string myObj::getObjectName()'
discards qualifiers
I tried to change around some data types but I still get the same error.
Any help would be appreciated.
Thanks.
Sofia.
Edit:Sorry I forgot to mention that if I use obj.name after taking of name from the private area and to the public my code compiles fine without any errors but I know that it's not the way to do it .
Last edited by megabyte; October 14th, 2003 at 04:56 AM.
Your problem is that CompareName :: operator() takes as it's argument a const reference to a myObj and your myObj::getObjectName() method is not declared as const. Try changing it's signature to:
Code:
string getObjectName() const {return name};
Best regards,
S. Bro
"I would be happy to deal with my problems one at the time if they would only line up!"
-Paul Cilwa, "Borland C++ Insider".
Other useful fora some of which I ruthlessly clipboarded from other peoples footers.
Sorry to bother you guys again, but I'm encountring a small problem that I think is due to my lack of knowledge as the whole std::list world is very new to me(I spent so much time learning vectors that I can't grasp well all what's going on with lists).
'nough said, what I'm trying to do is instead of using the following in main()
I want to use it in a let's say a member function of myObj.
I do so but I don't know how to keep the changes.Meaning that when I erase a member of the list and try to ouput the list I see that the removal was successful but what I need to do is append the changes to the list I'm working on in my main().
Code:
Myobj.EraseMember(Myobj,"Jones ");
When I define EraseMember(list,key) I make sure to make it's return type as list and then return the list at the end but still the list in the main scope stays unchanged while the one inside the function defenition scope changes.
I'm sure that I'm looking at it the wrong way so please advise.
Thanks in advance.
Sofia.
It seems to me you're moving into muddy waters here. You store myObjs in a list and then make the individual objects responsible for deleting themselves and eachother from that list. I think there's something wrong with this approach.
Also, your method:
Code:
Myobj.EraseMember(Myobj,"Jones ");
takes as it's first argument a pointer to a myObj even though EraseMember() is a member function and, as such, has access to the this pointer.
What are you trying to do? Erase a myObj from the list through another myObj contained in the same list? I suspect you're complicating matters unnecessarily...
Best regards,
S. Bro
"I would be happy to deal with my problems one at the time if they would only line up!"
-Paul Cilwa, "Borland C++ Insider".
Other useful fora some of which I ruthlessly clipboarded from other peoples footers.
Sorry if I didn't make myself clear enough but I'll try to catch up.
What I am trying to do is write a member function like let's say pop_front() or pop_back but which would erase an element of the list that is not in the front or the back but somewhere in the middle. the element would be chosen regarding it's name.
so let say I have a list of obj which have a name and an age.
so instead of saying something like
MyList.pop_front(); I would like to be able to pop an element with a name let's say "James". something like MyList.EraseMember("James");
Any help would be really appreciated.
Sofia.
Morning everyone,
Thank you for the reply sbrothy.I'm actually deriving from the STL list and eventhough I got to understand why I shouldn't be doing that I just have to do it as I have no choice
I didn't really grasp the idea of containment!! I would really appreciate it if you were to give me an idea on what it means.
Does it have to do with this line??
Code:
typedef list<myObj> OBJLIST, *POBJLIST;
I actually worked up my code a bit and now it compiles but the application crashes
this is the code I have:
Code:
template<class T>
class OrderedList: public list<T> {
public:
OrderedList();
~OrderedList();
void EraseMember(OrderedList<T>& MyList,string myKey);
};
once again I know that I am not supposed to inherit from the an stl container(as it's not a base class and hence has no virtual destructors...) .
Thanks for any help.
Sofia.
Bookmarks