lists and iterators and errors...oh my!

Mar 16, 2012 at 10:31am
I am trying to find a skill in a list of strings named Skills. I want to be able to remove said skill like this:

1
2
3
4
5
6
7
8
void Player::removeskill(const std::string skill)
{
    for(std::list<std::string>::iterator sit = Skills.begin(); sit !=Skills.end(); ++sit)
    {
		if(/*if the iteraor position has a skill named "std::string skill"*/)
        Skills.erase(*sit);
    }
}


(on a side note) This how I add skills:
1
2
3
4
void Player::addskill(std::string skill)
{
	Skills.push_back(skill);
}

This is the relevant(I think) part of my Player class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef PLAYER_H
#define PLAYER_H

/*
 * No description
 */
#include <list>
#include <string>
 
class Player
{
	// private section
	std::string skill;
	std::list<std::string> Skills;
    std::list<std::string>::iterator sit;
	public:
		void addskill(std::string skill);
		void removeskill(std::string skill);
	protected:
};

#endif // PLAYER_H 


The line that has if(/*if the iteraor position has a skill named "std::string */ is the one I am having trouble finding. I don't know how to test the data at the iterator's position in a function. Am I even doing this right in the first place?

Any help would be appreciated.
Mar 16, 2012 at 10:42am
To be honest, STL lists aren't great for random access.

You'd be better off swapping out that list for a STL vector. Then you could use the [] operator or the at() function to access elements at that point.
Mar 16, 2012 at 11:30am
What about boost containers?
Mar 16, 2012 at 11:38am
Someone else will have to field that one I'm afraid - I don't use the boost libraries.
Mar 16, 2012 at 11:53am
Just change your list for a set.
In addskill(), use insert() instead of push_back(). Skills will be sorted alpahabetically in the set at insertion, and will prevent multiple insertion of the same skill
Then use find() on the set for a given skill nalme (eventually with a custom comparison function if you want to find skill name with differnet upper/lower case characters)
Last edited on Mar 16, 2012 at 11:54am
Mar 16, 2012 at 12:25pm
bartoli,
Are you referring to the boost library or the STL library? I've never used boost but I'm told it has a lot of very good stuff in it. I don't recall hearing much about set's. So I am unsure which library contains a set container.

iHutch105,
Thanks for your help. The vector::at() seems promising. You say vector is better for random access?
Last edited on Mar 16, 2012 at 12:25pm
Mar 16, 2012 at 12:37pm
Yeah, because you can access the elements within the vector. The list only lets you access the element at the beginning or the end.
Mar 16, 2012 at 12:49pm
I have not understood what is the problem?

The question arises do you want to remove all elemennts in the list that are equal to a given sttring or only the first one?

To remove all elements equal to a given string you can use the combination of standard algorithm std::remove and list member function erase. For example

1
2
3
4
void Player::removeskill(const std::string &skill)
{
   Skills.erase( std:;remove( Skills.begin(), Skill.end(), skill ), Skills.end() ); 
}


To erase only the first element equal to a given string you can use standard algorithm std::find

1
2
3
4
void Player::removeskill(const std::string &skill)
{
   Skills.erase( std::find( Skills.begin(), Skills.end(), string ) ); 
}

Last edited on Mar 16, 2012 at 12:54pm
Topic archived. No new replies allowed.