Search code examples
c++c++11iteratorstdlist

Calling a function on a pointer from a std::list<Shape*>::iterator


I have a basic polymorphism example in C++ with the following structure.

struct Shape {
    virtual void draw() = 0;
};

struct Circle : public Shape {
    virtual void draw() {
        cout << "drawing circle" << endl;
    }
};

struct Triangle : public Shape {
    virtual void draw() {
        cout << "drawing triangle" << endl;
    }
};

I have a function using this setup to call the draw function as such:

void drawShapes(list<Shape*> shapes) {
    list<Shape*>::iterator pShape = shapes.begin();
    list<Shape*>::iterator pEnd = shapes.end();

    for (; pShape != pEnd; pShape++) {
        pShape->draw();
    }
}

This is exactly how the example is setup in the book I am reading. I am getting the following error when I try to compile this.

expression must have a pointer-to-class type

I fixed this by changing pShape->draw(); to (*pShape)->draw().

I then submitted this as a possible error to the writer of the book, to which he responded

"That's not the case, actually, because std::list::iterator has an operator->() function which resolves the iterator to a T* (in this case, Shape*)."

I still can't get the original version to compile though. I am using the compiler bundled with VS2015 to do these test. Does anyone know why I might be getting this error?


Solution

  • You're correct, and the author is wrong. std::list<T>::iterator::operator* returns a T*, this is true. But in this case, T is Shape*, which makes T* == Shape**. You need to dereference it once to get a Shape*. That is why pShape->draw() fails, but (*pShape)->draw() works.