Reputation: 47
I am trying to scroll a two dimensional list with an iterator and I know that I'm missing something but I don't know what.
So the idea is that I'll have some commands to parse.
I put them on a list then I want to check if a member of the list is equal to "data.txt" for example. So I did an iterator for this, but as it is a two dimensional list with an std::pair inside it, I don't know how to implement this iterator. I did this but it isn't good, I can't read both list.
typedef std::list<std::string> listStr;
std::list <std::pair<listStr, int> > _execCmd;
int Parser::execCmd()
{
std::list<std::string>::const_iterator i;
for (i = _execCmd.front().first.begin(); i != _execCmd.back().first.end(); ++i)
{
if (*i == "Search.txt")
execSearch();
else if (*i == "data.txt")
execData();
}
return (0);
}
In that case, I stay on the first list "File.txt data.txt contact.txt" (cf: schema) and I can go through the second list "Search.txt employe.csv".
I've tried this too:
int Parser::execCmd()
{
std::list<std::pair<listStr, int> >::const_iterator i;
for (i = _execCmd.begin(); i != _execCmd.end(); ++i)
{
if (*i == "Search.txt")
execSearch();
else if (*i == "data.txt")
execData();
}
return (0);
}
But I can't compile this because I don't know how to compare the iterator with a string (*i == "help"
)
Somebody can help me please ?
Upvotes: 0
Views: 2235
Reputation: 4406
As I said in the comments, the way to iterate over an std::list
in c++ is to use the foreach syntax.
The idea of an iterator is to give you a pointer-like access to elements in the container and to provide a way for the container to operate on these elements. For example, given an iterator you can delete an element in a list. Or you could insert an element at specific position.
What you need, however, is just to traverse over the list elements and check whether there is "search.txt" or "data.txt". So you don't need any iterators, you need just the elements. This is what the range-based for loop in c++ is. (Look at this great question: What is the correct way of using C++11's range-based for?)
Note that internally the range-based for loop internally may use iterators.
std::list<std::pair<listStr, int> >::const_iterator i;
for (std::pair<listStr, int> &elementFromOuterList: _execCmd) {
// now given that elementFromOuterList you can do whatever you need to
}
Upvotes: 0
Reputation: 36627
A std::pair<X,Y>
contains two members, first
which obtains the member of type X
and second
which obtains the member of type Y
.
In your case, thanks to the typedef
you have a std::list<std::pair<std::list<std::string>, int> >
.
So to iterate over all std::string
s in that structure, you need to iterate over the outer list to get the pairs, obtain the first
member from each of those (of type std::list<string>
, and iterate over ever element of that inner list.
int Parser::execCmd()
{
std::list<std::pair<listStr, int> >::const_iterator i;
for (i = _execCmd.begin(); i != _execCmd.end(); ++i)
{
// i->first is of type std::list<std:string>
for (j = i->first.begin(); j != i->first.end(); ++j)
{
if (*j == "Search.txt")
execSearch();
else if (*j == "data.txt")
execData();
}
}
return (0);
}
In C++11, it is simpler, but still necessary to nest loops.
int Parser::execCmd()
{
std::list<std::pair<listStr, int> >::const_iterator i;
for (const auto &i : _execCmd))
{
// i.first is of type std::list<std:string>
for (const auto &j : i.first)
{
if (j == "Search.txt")
execSearch();
else if (j == "data.txt")
execData();
}
}
return (0);
}
Upvotes: 1