Justin
Justin

Reputation: 213

Trouble using iterator on a list of objects

So I have a class called symbol, which is made up of 4 strings which are all public. I created a list of these and I want to do a look ahead on this list. This is what I have so far. I looked up the iterator methods and it says it supports the + operator but I get an error for this.

    bool parser::parse(list<symbol> myList){
    //Will read tokens by type to make sure that they pass the parse
    std::list<symbol>::const_iterator lookAhead = myList.begin();
    if ((lookAhead + 1) != myList.end)
        lookAhead++;
    for (std::list<symbol>::const_iterator it = myList.begin(); it != myList.end(); ++it){
        if (it->type == "") {

        }
    }

    return true;
}

I get an error when trying to add 1 to lookAhead. What are some good ways of creating a look ahead for a list?

Thanks, Binx

Upvotes: 0

Views: 273

Answers (1)

Cameron
Cameron

Reputation: 98886

A linked list does not support random access iterators, i.e. you cannot add an integer to its iterators.

Use std::next(lookAhead) to get the next iterator instead, or std::advance(lookAhead, 1). These functions know what kind of iterator is being passed, and will use a random seek if possible (e.g. with std::vector's random-access iterators), or manually advance (with a loop in the case of std::advance()) otherwise, as in this case.

Be careful advancing on iterators unconditionally, though -- advancing past end() is undefined!

You can read more about the different categories of C++ iterators here.

Side note: You're copying the entire list when it's passed in, since you're passing it by value. You probably want to pass it by reference instead (list<symbol> const& myList). You can also simplify your code using the C++11 auto keyword, which deduces the type automatically from the type of the expression that initializes the variable:

bool parser::parse(list<symbol> const& myList){
    // Will read tokens by type to make sure that they pass the parse
    auto lookAhead = myList.begin();
    if (lookAhead != myList.end() && std::next(lookAhead) != myList.end())
        ++lookAhead;
    for (auto it = myList.begin(); it != myList.end(); ++it){
        if (it->type == "") {

        }
    }
    return true;
}

Upvotes: 7

Related Questions